diff --git a/.gitignore b/.gitignore index 1dcb0521..de469da2 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,6 @@ CMakeLists.txt.user build* *.swp +.settings +# ignore mac temporal files +.DS_Store diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d24c8c1f..5d60107c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,50 +1,522 @@ -gcc-c++11: - script: "CI/ci-linux.sh gcc C++11" - tags: - - Linux +############################################################# +# # +# This is an auto generated file. Do not make # +# changes to this file. They possible will be overriden. # +# # +# To make persistent changes, changes files in # +# ./CI/gitlab-ci/ ... # +# and regenerate this file with the configuration tool # +# python3 ./CI/gitlab-ci/assemble-gitlab-ci.py # +# # +############################################################# -clang-c++11: - script: "CI/ci-linux.sh clang C++11" - tags: - - Linux +stages: + - build + - test + - deploy -gcc-c++14: - script: "CI/ci-linux.sh gcc C++14" - tags: - - Linux +variables: + GIT_SUBMODULE_STRATEGY: recursive -clang-c++14: - script: "CI/ci-linux.sh clang C++14" - tags: - - Linux - -macos-c++11: - script: "CI/ci-mac.sh C++11" - tags: - - Apple - artifacts: - paths: - - build-release-cpp11/*.dmg - - build-release-cpp11/*.tar.gz - -macos-c++98: - script: "CI/ci-mac.sh C++14" - tags: - - Apple - artifacts: - paths: - - build-release-cpp14/*.dmg - - build-release-cpp14/*.tar.gz +# ----------------- +# Linux tasks +# ----------------- cppcheck: + stage: build script: "CI/ci-cppcheck.sh" - tags: - - Linux + image: graphics.rwth-aachen.de:4567/docker/docker/docker-openmesh-container + tags: [Docker] + timeout: 3h artifacts: paths: - cppcheck.log -VS2015-64-bit-shared-apps: +#----------- Job Informations: +# Type: Build: debug +# OS: Linux +# Compiler: gcc +# Language: cpp11 + +build-debug-gcc-cpp11: + stage: build + script: "CI/ci-linux-build.sh gcc cpp11 debug" + image: graphics.rwth-aachen.de:4567/docker/docker/docker-openmesh-container + tags: [Docker] + artifacts: + paths: + - build-gcc-cpp11-debug-Vector-Checks/ + +#----------- Job Informations: +# Type: Test: debug +# OS: Linux +# Compiler: gcc +# Language: cpp11 + +test-debug-gcc-cpp11: + stage: test + script: "CI/ci-linux-test.sh gcc cpp11 debug" + image: graphics.rwth-aachen.de:4567/docker/docker/docker-openmesh-container + tags: [Docker] + dependencies: [build-debug-gcc-cpp11] + needs: [build-debug-gcc-cpp11] + artifacts: + reports: + junit: + - build-gcc-cpp11-debug-Vector-Checks/Unittests/report.xml + - build-gcc-cpp11-debug-Vector-Checks/Unittests/report-customvec.xml + - build-gcc-cpp11-debug-Vector-Checks/Unittests/report-doublevec.xml + + +#----------- Job Informations: +# Type: Build: release +# OS: Linux +# Compiler: gcc +# Language: cpp11 + +build-release-gcc-cpp11: + stage: build + script: "CI/ci-linux-build.sh gcc cpp11 release" + image: graphics.rwth-aachen.de:4567/docker/docker/docker-openmesh-container + tags: [Docker] + artifacts: + paths: + - build-gcc-cpp11-release-Vector-Checks/ + +#----------- Job Informations: +# Type: Test: release +# OS: Linux +# Compiler: gcc +# Language: cpp11 + +test-release-gcc-cpp11: + stage: test + script: "CI/ci-linux-test.sh gcc cpp11 release" + image: graphics.rwth-aachen.de:4567/docker/docker/docker-openmesh-container + tags: [Docker] + dependencies: [build-release-gcc-cpp11] + needs: [build-release-gcc-cpp11] + artifacts: + reports: + junit: + - build-gcc-cpp11-release-Vector-Checks/Unittests/report.xml + - build-gcc-cpp11-release-Vector-Checks/Unittests/report-customvec.xml + - build-gcc-cpp11-release-Vector-Checks/Unittests/report-doublevec.xml + + +#----------- Job Informations: +# Type: Build: debug +# OS: Linux +# Compiler: clang +# Language: cpp11 + +build-debug-clang-cpp11: + stage: build + script: "CI/ci-linux-build.sh clang cpp11 debug" + image: graphics.rwth-aachen.de:4567/docker/docker/docker-openmesh-container + tags: [Docker] + artifacts: + paths: + - build-clang-cpp11-debug-Vector-Checks/ + +#----------- Job Informations: +# Type: Test: debug +# OS: Linux +# Compiler: clang +# Language: cpp11 + +test-debug-clang-cpp11: + stage: test + script: "CI/ci-linux-test.sh clang cpp11 debug" + image: graphics.rwth-aachen.de:4567/docker/docker/docker-openmesh-container + tags: [Docker] + dependencies: [build-debug-clang-cpp11] + needs: [build-debug-clang-cpp11] + artifacts: + reports: + junit: + - build-clang-cpp11-debug-Vector-Checks/Unittests/report.xml + - build-clang-cpp11-debug-Vector-Checks/Unittests/report-customvec.xml + - build-clang-cpp11-debug-Vector-Checks/Unittests/report-doublevec.xml + + +#----------- Job Informations: +# Type: Build: release +# OS: Linux +# Compiler: clang +# Language: cpp11 + +build-release-clang-cpp11: + stage: build + script: "CI/ci-linux-build.sh clang cpp11 release" + image: graphics.rwth-aachen.de:4567/docker/docker/docker-openmesh-container + tags: [Docker] + artifacts: + paths: + - build-clang-cpp11-release-Vector-Checks/ + +#----------- Job Informations: +# Type: Test: release +# OS: Linux +# Compiler: clang +# Language: cpp11 + +test-release-clang-cpp11: + stage: test + script: "CI/ci-linux-test.sh clang cpp11 release" + image: graphics.rwth-aachen.de:4567/docker/docker/docker-openmesh-container + tags: [Docker] + dependencies: [build-release-clang-cpp11] + needs: [build-release-clang-cpp11] + artifacts: + reports: + junit: + - build-clang-cpp11-release-Vector-Checks/Unittests/report.xml + - build-clang-cpp11-release-Vector-Checks/Unittests/report-customvec.xml + - build-clang-cpp11-release-Vector-Checks/Unittests/report-doublevec.xml + + +#----------- Job Informations: +# Type: Build: debug +# OS: Linux +# Compiler: gcc +# Language: cpp14 + +build-debug-gcc-cpp14: + stage: build + script: "CI/ci-linux-build.sh gcc cpp14 debug" + image: graphics.rwth-aachen.de:4567/docker/docker/docker-openmesh-container + tags: [Docker] + artifacts: + paths: + - build-gcc-cpp14-debug-Vector-Checks/ + +#----------- Job Informations: +# Type: Test: debug +# OS: Linux +# Compiler: gcc +# Language: cpp14 + +test-debug-gcc-cpp14: + stage: test + script: "CI/ci-linux-test.sh gcc cpp14 debug" + image: graphics.rwth-aachen.de:4567/docker/docker/docker-openmesh-container + tags: [Docker] + dependencies: [build-debug-gcc-cpp14] + needs: [build-debug-gcc-cpp14] + artifacts: + reports: + junit: + - build-gcc-cpp14-debug-Vector-Checks/Unittests/report.xml + - build-gcc-cpp14-debug-Vector-Checks/Unittests/report-customvec.xml + - build-gcc-cpp14-debug-Vector-Checks/Unittests/report-doublevec.xml + + +#----------- Job Informations: +# Type: Build: release +# OS: Linux +# Compiler: gcc +# Language: cpp14 + +build-release-gcc-cpp14: + stage: build + script: "CI/ci-linux-build.sh gcc cpp14 release" + image: graphics.rwth-aachen.de:4567/docker/docker/docker-openmesh-container + tags: [Docker] + artifacts: + paths: + - build-gcc-cpp14-release-Vector-Checks/ + +#----------- Job Informations: +# Type: Test: release +# OS: Linux +# Compiler: gcc +# Language: cpp14 + +test-release-gcc-cpp14: + stage: test + script: "CI/ci-linux-test.sh gcc cpp14 release" + image: graphics.rwth-aachen.de:4567/docker/docker/docker-openmesh-container + tags: [Docker] + dependencies: [build-release-gcc-cpp14] + needs: [build-release-gcc-cpp14] + artifacts: + reports: + junit: + - build-gcc-cpp14-release-Vector-Checks/Unittests/report.xml + - build-gcc-cpp14-release-Vector-Checks/Unittests/report-customvec.xml + - build-gcc-cpp14-release-Vector-Checks/Unittests/report-doublevec.xml + + +#----------- Job Informations: +# Type: Build: debug +# OS: Linux +# Compiler: clang +# Language: cpp14 + +build-debug-clang-cpp14: + stage: build + script: "CI/ci-linux-build.sh clang cpp14 debug" + image: graphics.rwth-aachen.de:4567/docker/docker/docker-openmesh-container + tags: [Docker] + artifacts: + paths: + - build-clang-cpp14-debug-Vector-Checks/ + +#----------- Job Informations: +# Type: Test: debug +# OS: Linux +# Compiler: clang +# Language: cpp14 + +test-debug-clang-cpp14: + stage: test + script: "CI/ci-linux-test.sh clang cpp14 debug" + image: graphics.rwth-aachen.de:4567/docker/docker/docker-openmesh-container + tags: [Docker] + dependencies: [build-debug-clang-cpp14] + needs: [build-debug-clang-cpp14] + artifacts: + reports: + junit: + - build-clang-cpp14-debug-Vector-Checks/Unittests/report.xml + - build-clang-cpp14-debug-Vector-Checks/Unittests/report-customvec.xml + - build-clang-cpp14-debug-Vector-Checks/Unittests/report-doublevec.xml + + +#----------- Job Informations: +# Type: Build: release +# OS: Linux +# Compiler: clang +# Language: cpp14 + +build-release-clang-cpp14: + stage: build + script: "CI/ci-linux-build.sh clang cpp14 release" + image: graphics.rwth-aachen.de:4567/docker/docker/docker-openmesh-container + tags: [Docker] + artifacts: + paths: + - build-clang-cpp14-release-Vector-Checks/ + +#----------- Job Informations: +# Type: Test: release +# OS: Linux +# Compiler: clang +# Language: cpp14 + +test-release-clang-cpp14: + stage: test + script: "CI/ci-linux-test.sh clang cpp14 release" + image: graphics.rwth-aachen.de:4567/docker/docker/docker-openmesh-container + tags: [Docker] + dependencies: [build-release-clang-cpp14] + needs: [build-release-clang-cpp14] + artifacts: + reports: + junit: + - build-clang-cpp14-release-Vector-Checks/Unittests/report.xml + - build-clang-cpp14-release-Vector-Checks/Unittests/report-customvec.xml + - build-clang-cpp14-release-Vector-Checks/Unittests/report-doublevec.xml + + + +# ----------------- +# MAC tasks +# ----------------- + +#----------- Job Informations: +# Type: Build+Test: debug +# OS: Mac +# Language: cpp11 + +macos-cpp11-debug: + stage: build + script: "CI/ci-mac-build.sh cpp11 debug ; CI/ci-mac-test.sh cpp11 debug" + tags: + - Apple + artifacts: + paths: + - build-debug-cpp11/*.dmg + - build-debug-cpp11/*.tar.gz +# reports: +# junit: +# - build-debug-cpp11/Unittests/report.xml +# - build-debug-cpp11/Unittests/report-customvec.xml +# - build-debug-cpp11/Unittests/report-doublevec.xml + +#----------- Job Informations: +# Type: Build+Test: release +# OS: Mac +# Language: cpp11 + +macos-cpp11-release: + stage: build + script: "CI/ci-mac-build.sh cpp11 release ; CI/ci-mac-test.sh cpp11 release" + tags: + - Apple + artifacts: + paths: + - build-release-cpp11/*.dmg + - build-release-cpp11/*.tar.gz +# reports: +# junit: +# - build-release-cpp11/Unittests/report.xml +# - build-release-cpp11/Unittests/report-customvec.xml +# - build-release-cpp11/Unittests/report-doublevec.xml + + +#----------- Job Informations: +# Type: Build+Test: debug +# OS: Mac +# Language: cpp14 + +macos-cpp14-debug: + stage: build + script: "CI/ci-mac-build.sh cpp14 debug ; CI/ci-mac-test.sh cpp14 debug" + tags: + - Apple + artifacts: + paths: + - build-debug-cpp14/*.dmg + - build-debug-cpp14/*.tar.gz +# reports: +# junit: +# - build-debug-cpp14/Unittests/report.xml +# - build-debug-cpp14/Unittests/report-customvec.xml +# - build-debug-cpp14/Unittests/report-doublevec.xml + +#----------- Job Informations: +# Type: Build+Test: release +# OS: Mac +# Language: cpp14 + +macos-cpp14-release: + stage: build + script: "CI/ci-mac-build.sh cpp14 release ; CI/ci-mac-test.sh cpp14 release" + tags: + - Apple + artifacts: + paths: + - build-release-cpp14/*.dmg + - build-release-cpp14/*.tar.gz +# reports: +# junit: +# - build-release-cpp14/Unittests/report.xml +# - build-release-cpp14/Unittests/report-customvec.xml +# - build-release-cpp14/Unittests/report-doublevec.xml + + + +# ----------------- +# Windows tasks +# ----------------- + +#------------- Job Informations: +# Type: Build+Test: Release +# OS: Windows +# Architecture: x64 +# Shared: TRUE +# VS Version: VS2017 +# Apps: {{APPS}} + +build-VS2017-x64-shared-TRUE-apps: + stage: build + variables: + BUILD_PLATFORM: "VS2017" + ARCHITECTURE: "x64" + SHARED: "TRUE" + APPS: "ON" + script: "CI\\Windows.bat" + tags: + - VS2017 + - Qt5101 + artifacts: + paths: + - build-release/*.exe + reports: + junit: + - build-release/unittests/report.xml + - build-release/unittests/report-customvec.xml + - build-release/unittests/report-doublevec.xml + +build-VS2017-x64-shared-TRUE-no-apps: + stage: build + variables: + BUILD_PLATFORM: "VS2017" + ARCHITECTURE: "x64" + SHARED: "TRUE" + APPS: "OFF" + script: "CI\\Windows.bat" + tags: + - VS2017 + artifacts: + paths: + - build-release/*.exe + reports: + junit: + - build-release/unittests/report.xml + - build-release/unittests/report-customvec.xml + - build-release/unittests/report-doublevec.xml + +#------------- Job Informations: +# Type: Build+Test: Release +# OS: Windows +# Architecture: x64 +# Shared: FALSE +# VS Version: VS2017 +# Apps: {{APPS}} + +build-VS2017-x64-shared-FALSE-apps: + stage: build + variables: + BUILD_PLATFORM: "VS2017" + ARCHITECTURE: "x64" + SHARED: "FALSE" + APPS: "ON" + script: "CI\\Windows.bat" + tags: + - VS2017 + - Qt5101 + artifacts: + paths: + - build-release/*.exe + reports: + junit: + - build-release/unittests/report.xml + - build-release/unittests/report-customvec.xml + - build-release/unittests/report-doublevec.xml + +build-VS2017-x64-shared-FALSE-no-apps: + stage: build + variables: + BUILD_PLATFORM: "VS2017" + ARCHITECTURE: "x64" + SHARED: "FALSE" + APPS: "OFF" + script: "CI\\Windows.bat" + tags: + - VS2017 + artifacts: + paths: + - build-release/*.exe + reports: + junit: + - build-release/unittests/report.xml + - build-release/unittests/report-customvec.xml + - build-release/unittests/report-doublevec.xml + + +#------------- Job Informations: +# Type: Build+Test: Release +# OS: Windows +# Architecture: x64 +# Shared: TRUE +# VS Version: VS2015 +# Apps: {{APPS}} + +build-VS2015-x64-shared-TRUE-apps: + stage: build variables: BUILD_PLATFORM: "VS2015" ARCHITECTURE: "x64" @@ -53,11 +525,18 @@ VS2015-64-bit-shared-apps: script: "CI\\Windows.bat" tags: - VS2015 + - Qt5101 artifacts: paths: - build-release/*.exe - -VS2015-64-bit-shared-no-apps: + reports: + junit: + - build-release/unittests/report.xml + - build-release/unittests/report-customvec.xml + - build-release/unittests/report-doublevec.xml + +build-VS2015-x64-shared-TRUE-no-apps: + stage: build variables: BUILD_PLATFORM: "VS2015" ARCHITECTURE: "x64" @@ -69,34 +548,22 @@ VS2015-64-bit-shared-no-apps: artifacts: paths: - build-release/*.exe + reports: + junit: + - build-release/unittests/report.xml + - build-release/unittests/report-customvec.xml + - build-release/unittests/report-doublevec.xml -VS2015-32-bit-shared-apps: - variables: - BUILD_PLATFORM: "VS2015" - ARCHITECTURE: "x32" - SHARED: "TRUE" - APPS: "ON" - script: "CI\\Windows.bat" - tags: - - VS2015 - artifacts: - paths: - - build-release/*.exe +#------------- Job Informations: +# Type: Build+Test: Release +# OS: Windows +# Architecture: x64 +# Shared: FALSE +# VS Version: VS2015 +# Apps: {{APPS}} -VS2015-32-bit-shared-no-apps: - variables: - BUILD_PLATFORM: "VS2015" - ARCHITECTURE: "x32" - SHARED: "TRUE" - APPS: "OFF" - script: "CI\\Windows.bat" - tags: - - VS2015 - artifacts: - paths: - - build-release/*.exe - -VS2015-64-bit-static-apps: +build-VS2015-x64-shared-FALSE-apps: + stage: build variables: BUILD_PLATFORM: "VS2015" ARCHITECTURE: "x64" @@ -105,11 +572,18 @@ VS2015-64-bit-static-apps: script: "CI\\Windows.bat" tags: - VS2015 + - Qt5101 artifacts: paths: - build-release/*.exe + reports: + junit: + - build-release/unittests/report.xml + - build-release/unittests/report-customvec.xml + - build-release/unittests/report-doublevec.xml -VS2015-64-bit-static-no-apps: +build-VS2015-x64-shared-FALSE-no-apps: + stage: build variables: BUILD_PLATFORM: "VS2015" ARCHITECTURE: "x64" @@ -121,149 +595,34 @@ VS2015-64-bit-static-no-apps: artifacts: paths: - build-release/*.exe + reports: + junit: + - build-release/unittests/report.xml + - build-release/unittests/report-customvec.xml + - build-release/unittests/report-doublevec.xml -VS2015-32-bit-static-apps: - variables: - BUILD_PLATFORM: "VS2015" - ARCHITECTURE: "x32" - SHARED: "FALSE" - APPS: "ON" - script: "CI\\Windows.bat" - tags: - - VS2015 - artifacts: - paths: - - build-release/*.exe -VS2015-32-bit-static-no-apps: - variables: - BUILD_PLATFORM: "VS2015" - ARCHITECTURE: "x32" - SHARED: "FALSE" - APPS: "OFF" - script: "CI\\Windows.bat" - tags: - - VS2015 - artifacts: - paths: - - build-release/*.exe - - - -VS2013-64-bit-shared-apps: - variables: - BUILD_PLATFORM: "VS2013" - ARCHITECTURE: "x64" - SHARED: "TRUE" - APPS: "ON" - script: "CI\\Windows.bat" - tags: - - VS2013 - artifacts: - paths: - - build-release/*.exe - -VS2013-64-bit-shared-no-apps: - variables: - BUILD_PLATFORM: "VS2013" - ARCHITECTURE: "x64" - SHARED: "TRUE" - APPS: "OFF" - script: "CI\\Windows.bat" - tags: - - VS2013 - artifacts: - paths: - - build-release/*.exe - -VS2013-32-bit-shared-apps: - variables: - BUILD_PLATFORM: "VS2013" - ARCHITECTURE: "x32" - SHARED: "TRUE" - APPS: "ON" - script: "CI\\Windows.bat" - tags: - - VS2013 - artifacts: - paths: - - build-release/*.exe - -VS2013-32-bit-shared-no-apps: - variables: - BUILD_PLATFORM: "VS2013" - ARCHITECTURE: "x32" - SHARED: "TRUE" - APPS: "OFF" - script: "CI\\Windows.bat" - tags: - - VS2013 - artifacts: - paths: - - build-release/*.exe - -VS2013-64-bit-static-apps: - variables: - BUILD_PLATFORM: "VS2013" - ARCHITECTURE: "x64" - SHARED: "FALSE" - APPS: "ON" - script: "CI\\Windows.bat" - tags: - - VS2013 - artifacts: - paths: - - build-release/*.exe - -VS2013-64-bit-static-no-apps: - variables: - BUILD_PLATFORM: "VS2013" - ARCHITECTURE: "x64" - SHARED: "FALSE" - APPS: "OFF" - script: "CI\\Windows.bat" - tags: - - VS2013 - artifacts: - paths: - - build-release/*.exe - -VS2013-32-bit-static-apps: - variables: - BUILD_PLATFORM: "VS2013" - ARCHITECTURE: "x32" - SHARED: "FALSE" - APPS: "ON" - script: "CI\\Windows.bat" - tags: - - VS2013 - artifacts: - paths: - - build-release/*.exe - -VS2013-32-bit-static-no-apps: - variables: - BUILD_PLATFORM: "VS2013" - ARCHITECTURE: "x32" - SHARED: "FALSE" - APPS: "OFF" - script: "CI\\Windows.bat" - tags: - - VS2013 - artifacts: - paths: - - build-release/*.exe - Doc-publish: + stage: deploy only: - master script: "CI/ci-doc.sh" tags: - Linux - - - - - + - stretch + +Sources: + stage: deploy + only: + - master + script: "CI/ci-source.sh" + tags: + - Linux + - stretch + artifacts: + paths: + - OpenMesh*.zip + - OpenMesh*.tar.bz2 + - OpenMesh*.tar.gz diff --git a/.qmake.cache b/.qmake.cache deleted file mode 100644 index 20cb5b30..00000000 --- a/.qmake.cache +++ /dev/null @@ -1,15 +0,0 @@ -unix { - TOPDIR = $$system( pwd )/ -} - -win32 { - TOPDIR = $$system( cd )/ -} - -#use next qmake.cache if it exists -exists(../.qmake.cache) { - include( ../.qmake.cache ) -} - -include( qmake/all.include ) - diff --git a/CHANGELOG.md b/CHANGELOG.md index 6bd7a588..c82c7864 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -Please look into the doxygen configuration (Generated from Doc/history.docu) +The changelog can be found in the html Documentation. The latest changelog for the master can be found here: -http://openmesh.org/Daily-Builds/Doc/a00002.html +http://openmesh.org/Daily-Builds/Doc/ diff --git a/CI/Windows.bat b/CI/Windows.bat index 3db66708..616dcf27 100644 --- a/CI/Windows.bat +++ b/CI/Windows.bat @@ -16,39 +16,6 @@ IF "%SHARED%" == "TRUE" ( set STRING_DLL= ) -IF "%BUILD_PLATFORM%" == "VS2012" ( - set LIBPATH=E:\libs\VS2012 - set GTESTVERSION=gtest-1.6.0 - set GENERATOR=Visual Studio 11%ARCH_VS% - set VS_PATH="C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\devenv.com" - set QT_VERSION= - IF "%ARCHITECTURE%" == "x64" ( - set QT_INSTALL_PATH=E:\Qt\4.8.5-vs2012-%STRING_ARCH%\ - set QT_BASE_CONFIG=-DQT_QMAKE_EXECUTABLE=E:\Qt\4.8.5-vs2012-%STRING_ARCH%\bin\qmake.exe - ) - - IF "%ARCHITECTURE%" == "x32" ( - set QT_INSTALL_PATH=E:\Qt\4.8.5-vs2012-%STRING_ARCH%\ - set QT_BASE_CONFIG=-DQT_QMAKE_EXECUTABLE=E:\Qt\4.8.5-vs2012-%STRING_ARCH%\bin\qmake.exe - ) -) - -IF "%BUILD_PLATFORM%" == "VS2013" ( - set LIBPATH=E:\libs\VS2013 - set GTESTVERSION=gtest-1.6.0 - set GENERATOR=Visual Studio 12%ARCH_VS% - set VS_PATH="C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\devenv.com" - set QT_VERSION= - IF "%ARCHITECTURE%" == "x64" ( - set QT_INSTALL_PATH=E:\Qt\Qt5.3.1-vs2013-%STRING_ARCH%\5.3\msvc2013_64_opengl - set QT_BASE_CONFIG=-DQT5_INSTALL_PATH=E:\Qt\Qt5.3.1-vs2013-%STRING_ARCH%\5.3\msvc2013_64_opengl - ) - - IF "%ARCHITECTURE%" == "x32" ( - set QT_INSTALL_PATH=E:\Qt\Qt5.3.1-vs2013-%STRING_ARCH%\5.3\msvc2013_opengl - set QT_BASE_CONFIG=-DQT5_INSTALL_PATH=E:\Qt\Qt5.3.1-vs2013-%STRING_ARCH%\5.3\msvc2013_opengl - ) -) IF "%BUILD_PLATFORM%" == "VS2015" ( set LIBPATH=E:\libs\VS2015 @@ -56,7 +23,6 @@ IF "%BUILD_PLATFORM%" == "VS2015" ( set GENERATOR=Visual Studio 14%ARCH_VS% set VS_PATH="C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\devenv.com" - set QT_VERSION= IF "%ARCHITECTURE%" == "x64" ( set QT_INSTALL_PATH=E:\Qt\Qt5.6.0-vs2015-%STRING_ARCH%\5.6\msvc2015_64 set QT_BASE_CONFIG=-DQT5_INSTALL_PATH=E:\Qt\Qt5.6.0-vs2015-%STRING_ARCH%\5.6\msvc2015_64 @@ -69,31 +35,79 @@ IF "%BUILD_PLATFORM%" == "VS2015" ( ) +IF "%BUILD_PLATFORM%" == "VS2017" ( + set LIBPATH=E:\libs\VS2017 + set GTESTVERSION=gtest-1.7.0 + set GENERATOR=Visual Studio 15%ARCH_VS% + set VS_PATH="C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\IDE\devenv.com" + + IF "%ARCHITECTURE%" == "x64" ( + set QT_INSTALL_PATH=E:\Qt\Qt5.10.1\5.10.1\msvc2017_64 + set QT_BASE_CONFIG=-DQT5_INSTALL_PATH=E:\Qt\Qt5.10.1\5.10.1\msvc2017_64 + ) + +) + IF "%APPS%" == "ON" ( set STRING_APPS= + ECHO "Copying Platform plugins from %QT_INSTALL_PATH%\plugins\platforms to Build\plugins\platforms" + + + REM Create the platform plugins subdirectory for the qt plugins required to run the gui apps + mkdir Build mkdir Build\plugins mkdir Build\plugins\platforms - + REM Copy the platform plugins subdirectory for the qt plugins required to run the gui apps xcopy /Y %QT_INSTALL_PATH%\plugins\platforms Build\plugins\platforms - - IF "%BUILD_PLATFORM%" == "VS2015" ( - set CMAKE_CONFIGURATION=%QT_BASE_CONFIG% -DGLUT_INCLUDE_DIR="%LIBPATH%\%ARCHITECTURE%\freeglut-3.0.0\include" -DGLUT_glut_LIBRARY="%LIBPATH%\%ARCHITECTURE%\freeglut-3.0.0\lib\freeglut.lib" - - - ) ELSE ( - set CMAKE_CONFIGURATION=%QT_BASE_CONFIG% -DGLUT_INCLUDE_DIR="%LIBPATH%\%ARCHITECTURE%\freeglut-2.8.1\include" -DGLUT_glut_LIBRARY="%LIBPATH%\%ARCHITECTURE%\freeglut-2.8.1\lib\freeglut.lib" - ) + set CMAKE_CONFIGURATION=%QT_BASE_CONFIG% ) ELSE ( set STRING_APPS=-no-apps set CMAKE_CONFIGURATION= ) -"C:\Program Files (x86)\CMake\bin\cmake.exe" -DGTEST_PREFIX="%LIBPATH%\%ARCHITECTURE%\%GTESTVERSION%" -G "%GENERATOR%" -DCMAKE_BUILD_TYPE=Release -DBUILD_APPS=%APPS% -DOPENMESH_BUILD_UNIT_TESTS=TRUE -DCMAKE_WINDOWS_LIBS_DIR="e:\libs" -DOPENMESH_BUILD_SHARED=%SHARED% %CMAKE_CONFIGURATION% .. + + +ECHO "=============================================================" +ECHO "=============================================================" +ECHO "Building with :" +whoami +ECHO "ARCHITECTURE : %ARCHITECTURE%" +ECHO "BUILD_PLATFORM : %BUILD_PLATFORM%" +ECHO "GTESTVERSION : %GTESTVERSION%" +ECHO "GENERATOR : %GENERATOR%" +ECHO "VS_PATH : %VS_PATH%" +ECHO "LIBPATH : %LIBPATH%" +ECHO "APPS : %APPS%" +ECHO "SHARED : %SHARED%" +ECHO "QT_INSTALL_PATH : %QT_INSTALL_PATH%" +ECHO "CMAKE_CONFIGURATION : %CMAKE_CONFIGURATION%" +ECHO "=============================================================" +ECHO "=============================================================" +ECHO "" +ECHO "Running Build environment checks" + +IF EXIST %LIBPATH%\ ( + ECHO "LIBPATH ... Ok" +) ELSE ( + ECHO "LIBPATH not found!" + exit 10; +) + + +IF EXIST %QT_INSTALL_PATH%\ ( + ECHO "QT_INSTALL_PATH ... Ok" +) ELSE ( + ECHO "QT_INSTALL_PATH: %QT_INSTALL_PATH%\ not found!" + exit 10; +) + + +"C:\Program Files\CMake\bin\cmake.exe" -DGTEST_ROOT="%LIBPATH%\%ARCHITECTURE%\%GTESTVERSION%" -G "%GENERATOR%" -DCMAKE_BUILD_TYPE=Release -DBUILD_APPS=%APPS% -DOPENMESH_BUILD_UNIT_TESTS=TRUE -DCMAKE_WINDOWS_LIBS_DIR="e:\libs" -DOPENMESH_BUILD_SHARED=%SHARED% %CMAKE_CONFIGURATION% .. %VS_PATH% /Build "Release" OpenMesh.sln /Project "ALL_BUILD" @@ -101,7 +115,11 @@ IF %errorlevel% NEQ 0 exit /b %errorlevel% cd unittests -unittests.exe --gtest_output=xml +unittests.exe --gtest_output=xml:./report.xml + +unittests_customvec.exe --gtest_output=xml:./report-customvec.xml + +unittests_doublevec.exe --gtest_output=xml:./report-doublevec.xml cd .. @@ -111,7 +129,7 @@ mkdir build-debug cd build-debug -"C:\Program Files (x86)\CMake\bin\cmake.exe" -DGTEST_PREFIX="%LIBPATH%\%ARCHITECTURE%\%GTESTVERSION%" -G "%GENERATOR%" -DOPENMESH_BUILD_UNIT_TESTS=TRUE -DCMAKE_BUILD_TYPE=Debug -DOPENMESH_BUILD_SHARED=%SHARED% -DBUILD_APPS=%APPS% %CMAKE_CONFIGURATION% .. +"C:\Program Files\CMake\bin\cmake.exe" -DGTEST_ROOT="%LIBPATH%\%ARCHITECTURE%\%GTESTVERSION%" -G "%GENERATOR%" -DOPENMESH_BUILD_UNIT_TESTS=TRUE -DCMAKE_BUILD_TYPE=Debug -DOPENMESH_BUILD_SHARED=%SHARED% -DBUILD_APPS=%APPS% %CMAKE_CONFIGURATION% .. %VS_PATH% /Build "Debug" OpenMesh.sln /Project "ALL_BUILD" @@ -129,6 +147,10 @@ cd unittests unittests.exe --gtest_output=xml +unittests_customvec.exe --gtest_output=xml + +unittests_doublevec.exe --gtest_output=xml + IF %errorlevel% NEQ 0 exit /b %errorlevel% cd .. @@ -139,13 +161,13 @@ cd build-release del *.exe -"C:\Program Files (x86)\CMake\bin\cmake.exe" -DGTEST_PREFIX="%LIBPATH%\%ARCHITECTURE%\%GTESTVERSION%" -G "%GENERATOR%" -DBUILD_APPS=%APPS% -DCMAKE_BUILD_TYPE=Release %CMAKE_CONFIGURATION% .. +"C:\Program Files\CMake\bin\cmake.exe" -DGTEST_ROOT="%LIBPATH%\%ARCHITECTURE%\%GTESTVERSION%" -G "%GENERATOR%" -DBUILD_APPS=%APPS% -DCMAKE_BUILD_TYPE=Release %CMAKE_CONFIGURATION% .. %VS_PATH% /Build "Release" OpenMesh.sln /Project "PACKAGE" IF %errorlevel% NEQ 0 exit /b %errorlevel% -move OpenMesh-*.exe "OpenMesh-7.0-Git-Master-%CI_BUILD_REF%-%BUILD_PLATFORM%-%STRING_ARCH%%STRING_DLL%%STRING_APPS%.exe" +move OpenMesh-*.exe "OpenMesh-9.0-Git-Master-%CI_BUILD_REF%-%BUILD_PLATFORM%-%STRING_ARCH%%STRING_DLL%%STRING_APPS%.exe" diff --git a/CI/ci-cppcheck.sh b/CI/ci-cppcheck.sh index 43bc9824..7e73ab35 100755 --- a/CI/ci-cppcheck.sh +++ b/CI/ci-cppcheck.sh @@ -3,6 +3,8 @@ # Exit script on any error set -e +CPU_COUNT=$(grep -c processor /proc/cpuinfo) + #===================================== # Color Settings: #===================================== @@ -13,22 +15,14 @@ WARNING='\033[0;93m' echo -e "${OUTPUT}" echo "==============================================================================" echo "Running cppcheck" +echo -n "Version: " +cppcheck --version echo "==============================================================================" echo -e "${NC}" echo "Please Wait ..." # Run cppcheck and output into file -cppcheck --enable=all . -I src -i Doc/ --force --suppress=unusedFunction --suppress=missingIncludeSystem --quiet -Umin -Umax -UBMPOSTFIX -DOPENMESHDLLEXPORT="" &> cppcheck.log - -echo -e "${OUTPUT}" -echo "==============================================================================" -echo "CPPCHECK Messages" -echo "==============================================================================" -echo -e "${NC}" - - -# Echo output to command line for simple analysis via gitlab -cat cppcheck.log +cppcheck --enable=all . -I src -i Doc/ -i src/Unittests --force --suppress=unusedFunction -UCTIME --suppress=missingIncludeSystem --inline-suppr --quiet -Umin -Umax -DOPENMESHDLLEXPORT="" -UPRIVATE_NODE_TYPESYSTEM_SOURCE -USO_NODE_ABSTRACT_SOURCE -USO_NODE_SOURCE -UCLOCK_REALTIME_HR -i src/OpenMesh/Apps/Unsupported/ 2>&1 | tee cppcheck.log COUNT=$(wc -l < cppcheck.log ) @@ -38,7 +32,7 @@ echo "CPPCHECK Summary" echo "==============================================================================" echo -e "${NC}" -MAX_COUNT=6 +MAX_COUNT=23 if [ $COUNT -gt $MAX_COUNT ]; then echo -e ${WARNING} diff --git a/CI/ci-doc.sh b/CI/ci-doc.sh index 631df011..73505753 100755 --- a/CI/ci-doc.sh +++ b/CI/ci-doc.sh @@ -11,4 +11,4 @@ cmake -DCMAKE_BUILD_TYPE=Release -DOPENMESH_BUILD_UNIT_TESTS=FALSE ../ make doc # Copy to webserver -scp -r -P 2222 Build/share/OpenMesh/Doc/html/* hudson@web4-info8:OpenMesh-Daily/Doc/ +scp -r -P 2222 Build/share/OpenMesh/Doc/html/* gitlab@web4-info8:OpenMesh-Daily/Doc/ diff --git a/CI/ci-linux-build.sh b/CI/ci-linux-build.sh new file mode 100755 index 00000000..db28ab29 --- /dev/null +++ b/CI/ci-linux-build.sh @@ -0,0 +1,37 @@ +#!/bin/bash +source CI/ci-linux-prepare.sh + +echo -e "${OUTPUT}" +echo "" +echo "======================================================================" +echo "Basic configuration details:" +echo "======================================================================" +echo -e "${NC}" + +echo "Compiler: $COMPILER" +echo "Options: $OPTIONS" +echo "Language: $LANGUAGE" +echo "Make Options: $OPTIONS" +echo "BuildPath: $BUILDPATH" +echo "Path: $PATH" +echo "Language: $LANGUAGE" + +echo -e "${OUTPUT}" +echo "" +echo "======================================================================" +echo "Building $BUILD_TYPE version with vectorchecks enabled" +echo "======================================================================" +echo -e "${NC}" + +if [ ! -d build-$BUILDPATH-Vector-Checks ]; then + mkdir build-$BUILDPATH-Vector-Checks +fi + +cd build-$BUILDPATH-Vector-Checks + +cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DOPENMESH_BUILD_UNIT_TESTS=TRUE -DSTL_VECTOR_CHECKS=ON $OPTIONS ../ + +#build it +make $MAKE_OPTIONS + +cd .. \ No newline at end of file diff --git a/CI/ci-linux-prepare.sh b/CI/ci-linux-prepare.sh new file mode 100755 index 00000000..9153abea --- /dev/null +++ b/CI/ci-linux-prepare.sh @@ -0,0 +1,59 @@ +#!/bin/bash + +COMPILER=$1 +LANGUAGE=$2 +BUILD_TYPE=$3 + +# Exit script on any error +set -e + +OPTIONS="" +MAKE_OPTIONS="" +BUILDPATH="" + +# set GTEST path +OPTIONS="-DGTEST_ROOT=/usr/src/gtest/" + +if [ "$COMPILER" == "gcc" ]; then + echo "Building with GCC"; + BUILDPATH="gcc" + + # without icecc: no options required + OPTIONS="$OPTIONS -DCMAKE_CXX_COMPILER=/usr/bin/g++ -DCMAKE_C_COMPILER=/usr/bin/gcc" + MAKE_OPTIONS="-j16" + export ICECC_CXX=/usr/bin/g++ ; export ICECC_CC=/usr/bin/gcc + +elif [ "$COMPILER" == "clang" ]; then + + OPTIONS="$OPTIONS -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang" + echo "Building with CLANG"; + BUILDPATH="clang" +fi + +if [ "$LANGUAGE" == "cpp98" ]; then + echo "Building with C++98"; + BUILDPATH="$BUILDPATH-cpp98" +elif [ "$LANGUAGE" == "cpp11" ]; then + echo "Building with C++11"; + OPTIONS="$OPTIONS -DCMAKE_CXX_FLAGS='-std=c++11' " + BUILDPATH="$BUILDPATH-cpp11" +elif [ "$LANGUAGE" == "cpp14" ]; then + echo "Building with C++14"; + OPTIONS="$OPTIONS -DCMAKE_CXX_FLAGS='-std=c++14' " + BUILDPATH="$BUILDPATH-cpp14" +fi + +#===================================== +# Color Settings: +#===================================== +NC='\033[0m' +OUTPUT='\033[0;32m' +WARNING='\033[0;93m' + +if [ "$BUILD_TYPE" == "release" ]; then + export BUILD_TYPE=release + BUILDPATH="$BUILDPATH-release" +else + export BUILD_TYPE=debug + BUILDPATH="$BUILDPATH-debug" +fi \ No newline at end of file diff --git a/CI/ci-linux-test.sh b/CI/ci-linux-test.sh new file mode 100755 index 00000000..a9cc5fa8 --- /dev/null +++ b/CI/ci-linux-test.sh @@ -0,0 +1,70 @@ +#!/bin/bash +source CI/ci-linux-prepare.sh + +echo -e "${OUTPUT}" +echo "" +echo "======================================================================" +echo "Basic configuration details:" +echo "======================================================================" +echo -e "${NC}" + +echo "Compiler: $COMPILER" +echo "Options: $OPTIONS" +echo "Language: $LANGUAGE" +echo "Make Options: $OPTIONS" +echo "BuildPath: $BUILDPATH" +echo "Path: $PATH" +echo "Language: $LANGUAGE" + +echo -e "${OUTPUT}" +echo "" +echo "======================================================================" +echo "Building $BUILD_TYPE version unittests" +echo "======================================================================" +echo -e "${NC}" + +if [ ! -d build-$BUILDPATH-Vector-Checks ]; then + mkdir build-$BUILDPATH-Vector-Checks +fi + +cd build-$BUILDPATH-Vector-Checks + +#build the unit tests +make $MAKE_OPTIONS unittests + +echo -e "${OUTPUT}" +echo "" +echo "======================================================================" +echo "Running unittests $BUILD_TYPE version with vectorchecks enabled" +echo "======================================================================" +echo -e "${NC}" + +cd Unittests + +#execute tests +./unittests --gtest_color=yes --gtest_output=xml:./report.xml + +echo -e "${OUTPUT}" +echo "" +echo "======================================================================" +echo "Running unittests $BUILD_TYPE version with custom vector type" +echo "======================================================================" +echo -e "${NC}" + +./unittests_customvec --gtest_color=yes --gtest_output=xml:./report-customvec.xml + +echo -e "${OUTPUT}" +echo "" +echo "======================================================================" +echo "Running unittests $BUILD_TYPE version with double vector type" +echo "======================================================================" +echo -e "${NC}" + +#execute tests +./unittests_doublevec --gtest_color=yes --gtest_output=xml:./report-doublevec.xml + +pwd +ls *.xml + +cd .. +cd .. diff --git a/CI/ci-linux.sh b/CI/ci-linux.sh deleted file mode 100755 index f7632198..00000000 --- a/CI/ci-linux.sh +++ /dev/null @@ -1,222 +0,0 @@ -#!/bin/bash - -COMPILER=$1 -LANGUAGE=$2 - -# Exit script on any error -set -e - -OPTIONS="" -MAKE_OPTIONS="" -BUILDPATH="" - -if [ "$COMPILER" == "gcc" ]; then - echo "Building with GCC"; - BUILDPATH="gcc" - - # without icecc: no options required - OPTIONS="-DCMAKE_CXX_COMPILER=/usr/lib/icecc/bin/g++ -DCMAKE_C_COMPILER=/usr/lib/icecc/bin/gcc" - MAKE_OPTIONS="-j16" - export ICECC_CXX=/usr/bin/g++ ; export ICECC_CC=/usr/bin/gcc - -elif [ "$COMPILER" == "clang" ]; then - - OPTIONS="$OPTIONS -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang" - echo "Building with CLANG"; - BUILDPATH="clang" -fi - -if [ "$LANGUAGE" == "C++98" ]; then - echo "Building with C++98"; - BUILDPATH="$BUILDPATH-cpp98" -elif [ "$LANGUAGE" == "C++11" ]; then - echo "Building with C++11"; - OPTIONS="$OPTIONS -DCMAKE_CXX_FLAGS='-std=c++11' " - BUILDPATH="$BUILDPATH-cpp11" -elif [ "$LANGUAGE" == "C++14" ]; then - echo "Building with C++14"; - OPTIONS="$OPTIONS -DCMAKE_CXX_FLAGS='-std=c++14' " - BUILDPATH="$BUILDPATH-cpp14" -fi - -#===================================== -# Color Settings: -#===================================== -NC='\033[0m' -OUTPUT='\033[0;32m' -WARNING='\033[0;93m' - - -echo -e "${OUTPUT}" -echo "" -echo "======================================================================" -echo "Basic configuration details:" -echo "======================================================================" -echo -e "${NC}" - -echo "Compiler: $COMPILER" -echo "Options: $OPTIONS" -echo "Language: $LANGUAGE" -echo "Make Options: $OPTIONS" -echo "BuildPath: $BUILDPATH" -echo "Path: $PATH" -echo "Language: $LANGUAGE" - -echo -e "${OUTPUT}" -echo "" -echo "======================================================================" -echo "Building Release version with vectorchecks enabled" -echo "======================================================================" -echo -e "${NC}" - - -if [ ! -d build-release-$BUILDPATH-Vector-Checks ]; then - mkdir build-release-$BUILDPATH-Vector-Checks -fi - -cd build-release-$BUILDPATH-Vector-Checks - -cmake -DCMAKE_BUILD_TYPE=Release -DOPENMESH_BUILD_UNIT_TESTS=TRUE -DSTL_VECTOR_CHECKS=ON -DOPENMESH_BUILD_PYTHON_BINDINGS=OFF $OPTIONS ../ - -#build it -make $MAKE_OPTIONS - -#build the unit tests -make $MAKE_OPTIONS unittests - -echo -e "${OUTPUT}" -echo "" -echo "======================================================================" -echo "Running unittests Release version with vectorchecks enabled" -echo "======================================================================" -echo -e "${NC}" - -cd Unittests - -#execute tests -./unittests --gtest_color=yes --gtest_output=xml - -cd .. -cd .. - -echo -e "${OUTPUT}" -echo "" -echo "======================================================================" -echo "Building Release version with vectorchecks disabled for python tests" -echo "======================================================================" -echo -e "${NC}" - -if [ ! -d build-release-$BUILDPATH ]; then - mkdir build-release-$BUILDPATH -fi - -cd build-release-$BUILDPATH - -cmake -DCMAKE_BUILD_TYPE=Release -DOPENMESH_BUILD_PYTHON_UNIT_TESTS=ON -DBUILD_APPS=OFF $OPTIONS ../ - -#build it -make $MAKE_OPTIONS - -echo -e "${OUTPUT}" -echo "" -echo "======================================================================" -echo "Running Python unittests Release version " -echo "======================================================================" -echo -e "${NC}" - -if [ "$LANGUAGE" == "C++11" ] || [ "$COMPILER" == "gcc" ] ; then - - # Execute Python unittests - cd Python-Unittests - - python -m unittest discover -v - - cd .. - -else - echo -e "${WARNING}" - echo "WARNING! Python unittests disabled !!" - echo -e "${NC}" -fi - - -cd .. - - - -echo -e "${OUTPUT}" -echo "" -echo "======================================================================" -echo "Building Debug version with vectorchecks enabled" -echo "======================================================================" -echo -e "${NC}" - - -if [ ! -d build-debug-$BUILDPATH-Vector-Checks ]; then - mkdir build-debug-$BUILDPATH-Vector-Checks -fi - -cd build-debug-$BUILDPATH-Vector-Checks - -cmake -DCMAKE_BUILD_TYPE=Debug -DOPENMESH_BUILD_UNIT_TESTS=TRUE -DSTL_VECTOR_CHECKS=ON -DOPENMESH_BUILD_PYTHON_BINDINGS=OFF $OPTIONS ../ - -#build it -make $MAKE_OPTIONS - -#build the unit tests -make $MAKE_OPTIONS unittests - -echo -e "${OUTPUT}" -echo "" -echo "======================================================================" -echo "Running unittests Debug version with vectorchecks enabled" -echo "======================================================================" -echo -e "${NC}" - - -cd Unittests - -#execute tests -./unittests --gtest_color=yes --gtest_output=xml - -cd .. -cd .. - -echo -e "${OUTPUT}" -echo "" -echo "======================================================================" -echo "Building Debug version with vectorchecks disabled for python tests" -echo "======================================================================" -echo -e "${NC}" - -if [ ! -d build-debug-$BUILDPATH ]; then - mkdir build-debug-$BUILDPATH -fi - -cd build-debug-$BUILDPATH - -cmake -DCMAKE_BUILD_TYPE=DEBUG -DOPENMESH_BUILD_PYTHON_UNIT_TESTS=ON -DBUILD_APPS=OFF $OPTIONS ../ - -#build it -make $MAKE_OPTIONS - -echo -e "${OUTPUT}" -echo "" -echo "======================================================================" -echo "Running Python unittests Debug version " -echo "======================================================================" -echo -e "${NC}" - -if [ "$LANGUAGE" == "C++11" ] || [ "$COMPILER" == "gcc" ] ; then - - # Execute Python unittests - cd Python-Unittests - - python -m unittest discover -v -else - - echo -e "${WARNING}" - echo "WARNING! Python unittests disabled !!" - echo -e "${NC}" - -fi diff --git a/CI/ci-mac-build.sh b/CI/ci-mac-build.sh new file mode 100755 index 00000000..58b527de --- /dev/null +++ b/CI/ci-mac-build.sh @@ -0,0 +1,63 @@ +#!/bin/bash +source CI/ci-mac-prepare.sh + +echo -e "${OUTPUT}" +echo "" +echo "======================================================================" +echo "Basic configuration details:" +echo "======================================================================" +echo -e "${NC}" + +echo "Options: $OPTIONS" +echo "BuildPath: $BUILDPATH" +echo "Path: $PATH" +echo "Language: $LANGUAGE" + +cmake --version + +echo -e "${OUTPUT}" +echo "" +echo "======================================================================" +echo "Building $BUILD_TYPE version with vectorchecks enabled" +echo "======================================================================" +echo -e "${NC}" + + +if [ ! -d build-$BUILD_TYPE_L-$BUILDPATH-Vector-Checks ]; then + mkdir build-$BUILD_TYPE_L-$BUILDPATH-Vector-Checks +fi + +cd build-$BUILD_TYPE_L-$BUILDPATH-Vector-Checks + +cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DOPENMESH_BUILD_UNIT_TESTS=TRUE -DSTL_VECTOR_CHECKS=ON $OPTIONS ../ + +#build it +make + +cd .. + +if [ "$BUILD_TYPE_L" == "release" ]; then + + echo -e "${OUTPUT}" + echo "" + echo "======================================================================" + echo "Package creation (DMG and tarball)" + echo "======================================================================" + echo -e "${NC}" + + + if [ ! -d build-release-$BUILDPATH ]; then + mkdir build-release-$BUILDPATH + fi + + cd build-release-$BUILDPATH + + cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_APPS=OFF -DCPACK_BINARY_DRAGNDROP=ON $OPTIONS ../ + + #build it + make + make package + + cd .. + +fi diff --git a/CI/ci-mac-prepare.sh b/CI/ci-mac-prepare.sh new file mode 100755 index 00000000..39cf1f35 --- /dev/null +++ b/CI/ci-mac-prepare.sh @@ -0,0 +1,43 @@ +#!/bin/bash + +#Exit on any error +set -e + +LANGUAGE=$1 +BUILD_TYPE=$2 + +PATH=$PATH:/opt/local/bin +export PATH + +OPTIONS="" + +# set GTEST path +OPTIONS="$OPTIONS -DGTEST_ROOT=~/sw/gtest-1.7.0/" + +if [ "$LANGUAGE" == "cpp98" ]; then + echo "Building with C++98"; + BUILDPATH="cpp98" +elif [ "$LANGUAGE" == "cpp11" ]; then + echo "Building with C++11"; + OPTIONS="$OPTIONS -DCMAKE_CXX_FLAGS='-std=c++11' " + BUILDPATH="cpp11" +elif [ "$LANGUAGE" == "cpp14" ]; then + echo "Building with C++14"; + OPTIONS="$OPTIONS -DCMAKE_CXX_FLAGS='-std=c++14' " + BUILDPATH="cpp14" +fi + +#===================================== +# Color Settings: +#===================================== +NC='\033[0m' +OUTPUT='\033[0;32m' +WARNING='\033[0;93m' + +if [ "$BUILD_TYPE" == "release" ]; then + export BUILD_TYPE=Release + export BUILD_TYPE_L=release +else + export BUILD_TYPE=Debug + export BUILD_TYPE_L=debug +fi diff --git a/CI/ci-mac-test.sh b/CI/ci-mac-test.sh new file mode 100755 index 00000000..deeee00d --- /dev/null +++ b/CI/ci-mac-test.sh @@ -0,0 +1,65 @@ +#!/bin/bash +source CI/ci-mac-prepare.sh + +echo -e "${OUTPUT}" +echo "" +echo "======================================================================" +echo "Basic configuration details:" +echo "======================================================================" +echo -e "${NC}" + +echo "Options: $OPTIONS" +echo "BuildPath: $BUILDPATH" +echo "Path: $PATH" +echo "Language: $LANGUAGE" + +echo -e "${OUTPUT}" +echo "" +echo "======================================================================" +echo "Building $BUILD_TYPE version unittests" +echo "======================================================================" +echo -e "${NC}" + + +if [ ! -d build-$BUILD_TYPE_L-$BUILDPATH-Vector-Checks ]; then + mkdir build-$BUILD_TYPE_L-$BUILDPATH-Vector-Checks +fi + +cd build-$BUILD_TYPE_L-$BUILDPATH-Vector-Checks + +#build the unit tests +make unittests + +echo -e "${OUTPUT}" +echo "" +echo "======================================================================" +echo "Running unittests $BUILD_TYPE version with vectorchecks enabled" +echo "======================================================================" +echo -e "${NC}" + +cd Unittests + +#execute tests +./unittests --gtest_color=yes --gtest_output=xml:./report.xml + +echo -e "${OUTPUT}" +echo "" +echo "======================================================================" +echo "Running unittests $BUILD_TYPE version with minimal vector type" +echo "======================================================================" +echo -e "${NC}" + +./unittests_customvec --gtest_color=yes --gtest_output=xml:./report-customvec.xml + +echo -e "${OUTPUT}" +echo "" +echo "======================================================================" +echo "Running unittests $BUILD_TYPE version with double vector type" +echo "======================================================================" +echo -e "${NC}" + +#execute tests +./unittests_doublevec --gtest_color=yes --gtest_output=xml:./report-doublevec.xml + +cd .. +cd .. \ No newline at end of file diff --git a/CI/ci-mac.sh b/CI/ci-mac.sh deleted file mode 100755 index 9dd14577..00000000 --- a/CI/ci-mac.sh +++ /dev/null @@ -1,228 +0,0 @@ -#!/bin/bash - -#Exit on any error -set -e - -LANGUAGE=$1 - - -PATH=$PATH:/opt/local/bin -export PATH - -OPTIONS="" - -if [ "$LANGUAGE" == "C++98" ]; then - echo "Building with C++98"; - BUILDPATH="cpp98" -elif [ "$LANGUAGE" == "C++11" ]; then - echo "Building with C++11"; - OPTIONS="$OPTIONS -DCMAKE_CXX_FLAGS='-std=c++11' " - BUILDPATH="cpp11" -elif [ "$LANGUAGE" == "C++14" ]; then - echo "Building with C++14"; - OPTIONS="$OPTIONS -DCMAKE_CXX_FLAGS='-std=c++14' " - BUILDPATH="cpp14" -fi - -#===================================== -# Color Settings: -#===================================== -NC='\033[0m' -OUTPUT='\033[0;32m' -WARNING='\033[0;93m' - - -echo -e "${OUTPUT}" -echo "" -echo "======================================================================" -echo "Basic configuration details:" -echo "======================================================================" -echo -e "${NC}" - -echo "Options: $OPTIONS" -echo "BuildPath: $BUILDPATH" -echo "Path: $PATH" -echo "Language: $LANGUAGE" - -echo -e "${OUTPUT}" -echo "" -echo "======================================================================" -echo "Building Release version with vectorchecks enabled" -echo "======================================================================" -echo -e "${NC}" - - -if [ ! -d build-release-$BUILDPATH-Vector-Checks ]; then - mkdir build-release-$BUILDPATH-Vector-Checks -fi - -cd build-release-$BUILDPATH-Vector-Checks - -cmake -DCMAKE_BUILD_TYPE=Release -DOPENMESH_BUILD_UNIT_TESTS=TRUE -DSTL_VECTOR_CHECKS=ON -DOPENMESH_BUILD_PYTHON_UNIT_TESTS=OFF $OPTIONS ../ - -#build it -make - -#build the unit tests -make unittests - -echo -e "${OUTPUT}" -echo "" -echo "======================================================================" -echo "Running unittests Release version with vectorchecks enabled" -echo "======================================================================" -echo -e "${NC}" - -cd Unittests - -#execute tests -./unittests --gtest_color=yes --gtest_output=xml - -cd .. -cd .. - -echo -e "${OUTPUT}" -echo "" -echo "======================================================================" -echo "Building Release version with vectorchecks disabled for python tests" -echo "======================================================================" -echo -e "${NC}" - -if [ ! -d build-release-$BUILDPATH ]; then - mkdir build-release-$BUILDPATH -fi - -cd build-release-$BUILDPATH - -cmake -DCMAKE_BUILD_TYPE=Release -DOPENMESH_BUILD_PYTHON_UNIT_TESTS=ON -DBUILD_APPS=OFF -DCPACK_BINARY_DRAGNDROP=ON $OPTIONS ../ - -#build it -make - -echo -e "${OUTPUT}" -echo "" -echo "======================================================================" -echo "Running Python unittests Release version " -echo "======================================================================" -echo -e "${NC}" - - -if [ "$LANGUAGE" == "C++11" ]; then - - # Execute Python unittests - cd Python-Unittests - - rm -f openmesh.so - cp ../Build/python/openmesh.so . - python -m unittest discover -v - - cd .. - -else - echo -e "${WARNING}" - echo "WARNING! Python unittests disabled for clang on Mac with c++98 !!" - echo -e "${NC}" -fi - -cd .. - - - -echo -e "${OUTPUT}" -echo "" -echo "======================================================================" -echo "Building Debug version with vectorchecks enabled" -echo "======================================================================" -echo -e "${NC}" - - -if [ ! -d build-debug-$BUILDPATH-Vector-Checks ]; then - mkdir build-debug-$BUILDPATH-Vector-Checks -fi - -cd build-debug-$BUILDPATH-Vector-Checks - -cmake -DCMAKE_BUILD_TYPE=Debug -DOPENMESH_BUILD_UNIT_TESTS=TRUE -DSTL_VECTOR_CHECKS=ON -DOPENMESH_BUILD_PYTHON_UNIT_TESTS=OFF $OPTIONS ../ - -#build it -make - -#build the unit tests -make unittests - -echo -e "${OUTPUT}" -echo "" -echo "======================================================================" -echo "Running unittests Debug version with vectorchecks enabled" -echo "======================================================================" -echo -e "${NC}" - - -cd Unittests - -#execute tests -./unittests --gtest_color=yes --gtest_output=xml - -cd .. -cd .. - -echo -e "${OUTPUT}" -echo "" -echo "======================================================================" -echo "Building Debug version with vectorchecks disabled for python tests" -echo "======================================================================" -echo -e "${NC}" - -if [ ! -d build-debug-$BUILDPATH ]; then - mkdir build-debug-$BUILDPATH -fi - -cd build-debug-$BUILDPATH - -cmake -DCMAKE_BUILD_TYPE=DEBUG -DOPENMESH_BUILD_PYTHON_UNIT_TESTS=ON -DBUILD_APPS=OFF $OPTIONS ../ - -#build it -make - -echo -e "${OUTPUT}" -echo "" -echo "======================================================================" -echo "Running Python unittests Debug version " -echo "======================================================================" -echo -e "${NC}" - -if [ "$LANGUAGE" == "C++11" ]; then - - # Execute Python unittests - cd Python-Unittests - - rm -f openmesh.so - cp ../Build/python/openmesh.so . - python -m unittest discover -v - - cd .. - -else - - echo -e "${WARNING}" - echo "WARNING! Python unittests disabled for clang on Mac with c++98 !!" - echo -e "${NC}" - -fi - -cd .. - -echo -e "${OUTPUT}" -echo "" -echo "======================================================================" -echo "Package creation (DMG and tarball)" -echo "======================================================================" -echo -e "${NC}" - -cd build-release-$BUILDPATH -cp ../build-debug-$BUILDPATH/Build/lib/* ./Build/lib/ -cmake . -make package - - - diff --git a/CI/ci-source.sh b/CI/ci-source.sh new file mode 100755 index 00000000..5f0a4c18 --- /dev/null +++ b/CI/ci-source.sh @@ -0,0 +1,35 @@ + +# This script just creates compressed files of OpenMesh sources + +# Create Build directory and Build documentation +mkdir build-doc + +cd build-doc +cmake .. +make doc +cd .. + +# Extract Version Information +VERSION=OpenMesh-$(cat VERSION | grep VERSION | tr -d "VERSION=") + +# Create Publishing directory +mkdir $VERSION + +# Move all files into Publishing directory +mv CHANGELOG.md $VERSION/ +mv cmake $VERSION/ +mv CMakeLists.txt $VERSION/ +mv debian $VERSION/ +mv Doc $VERSION/ +mv LICENSE $VERSION/ +mv README.md $VERSION/ +mv src $VERSION/ +mv VERSION $VERSION/ +mv openmesh.pc.in $VERSION/ + +mv build-doc/Build/share/OpenMesh/Doc/html/ $VERSION/Documentation + +tar cjf $VERSION.tar.bz2 $VERSION +tar czf $VERSION.tar.gz $VERSION +zip -9 -q -r $VERSION.zip $VERSION + diff --git a/CI/gitlab-ci/assemble-gitlab-ci.py b/CI/gitlab-ci/assemble-gitlab-ci.py new file mode 100755 index 00000000..02b2eade --- /dev/null +++ b/CI/gitlab-ci/assemble-gitlab-ci.py @@ -0,0 +1,176 @@ +#!/usr/bin/python3 + +import sys, os, re, yaml, hashlib + +# Version 3.2 + +# Script for automated gitlab-ci creation +# Assembles the gitlab ci from master template file: +master_file = 'ci-master.yml' +# Lines in the master file are copied to the resulting +# assemblied gitlab ci file +target_file = '../../.gitlab-ci.yml' +# Lines that are {xxx} Strings are interpreted +# as import statement. Therefore the file xxx is imported +# into that line. +# Lines that are {xxx,option1=...,option2=...} includes +# the file xxx but replaces {{option1}} etc with specified +# string. +error_on_path_redirection = True +# Notice that xxx can not contain path redirections +# like .. and / + +# Max import recursion +maxFileRecursionDepth = 4 +# Max filename used for pretty print +maxFilnameChars = 30 + + +# Prefix to prepend to master file +autogenerated_notice = """############################################################# +# # +# This is an auto generated file. Do not make # +# changes to this file. They possible will be overriden. # +# # +# To make persistent changes, changes files in # +# ./CI/gitlab-ci/ ... # +# and regenerate this file with the configuration tool # +# python3 ./CI/gitlab-ci/assemble-gitlab-ci.py # +# # +############################################################# + +""" + + +# Checks if an import filename is valid - free of path redirections +def isValidImportFilename(filenameToImport): + if not error_on_path_redirection: + return True + else: + filterRegex = r"(\/|\\|\.\.+)" + filtered = re.sub(filterRegex, '', filenameToImport) + return filenameToImport == filtered + +# Returns the directory to work on +def findCIAssemblyDirectory(): + pathname = os.path.dirname(sys.argv[0]) + return os.path.abspath(pathname) + +# Returns file content as string +def readFile(filename): + file = open(filename, "r") + content = file.read() + file.close() + return content + +# Parse File Import String for variable replacements +def fetchVariableReplacers(variablesGrep): + if (variablesGrep == None): + return {} + + regex_option = r"([^\}\n\=,]+)\=([^\}\n\=,]+)" + pattern = re.compile(regex_option, flags=re.MULTILINE) + result = {} + + for (key, value) in re.findall(pattern, variablesGrep): + + if (key != None and value != None): + key = key.strip() + result[key] = value + + return result + + +# Assembles the file in memory and returns file content as string +def assembleTarget(master, depth=maxFileRecursionDepth): + if depth < 0: + raise "Max depth reached. Possible circular import?" + print_prefix = "" + for _ in range(0, maxFileRecursionDepth-depth): + print_prefix = print_prefix + " | \t" + print_prefix_inverse = "" + for _ in range(0, depth): + print_prefix_inverse = print_prefix_inverse + "\t" + + master_content = readFile(master) + regex_import_stmt = r"^\ *\{([^\},\n]+)(,[^=\n\}\,]+\=[^\}\n,]*)*\}\ *$" + regex_import_comp = re.compile(regex_import_stmt) + master_content_list = master_content.splitlines() + + # Walk through file looking for import statements + cur_index = 0 + while cur_index < len(master_content_list): + cur_line = master_content_list[cur_index] + match = regex_import_comp.match(cur_line) + + if match: + importFile = match.groups()[0] + if importFile: + # Found import statement + print(print_prefix+"Importing file: "+importFile.ljust(maxFilnameChars), end="") + + if not isValidImportFilename(importFile): + raise "Invalid filename "+importFile+ ". Do not include path redirections" + + variablesGrep = match.string + variableReplacers = fetchVariableReplacers(variablesGrep) + + print(print_prefix_inverse, variableReplacers) + + import_content = assembleTarget(importFile, depth=depth-1) + + for key, value in variableReplacers.items(): + import_content = import_content.replace(r"{{"+key+r"}}", value) + + import_content_list = import_content.splitlines() + master_content_list.pop(cur_index) + for new_line in reversed(import_content_list): + master_content_list.insert(cur_index, new_line) + + cur_index += 1 + + # Assemble result + master_content = ''.join(str(e)+'\n' for e in master_content_list) + return master_content + +# Main function +def main(): + print("Starting config assembly") + os.chdir(findCIAssemblyDirectory()) + target_content = autogenerated_notice + target_content += assembleTarget(master_file) + + m = hashlib.sha256() + m.update(readFile(target_file).encode('utf-8')) + hash_original = m.hexdigest() + m = hashlib.sha256() + m.update(target_content.encode('utf-8')) + m.update("\n".encode('utf-8')) + hash_new = m.hexdigest() + + print("Old checksum: ", hash_original) + print("New checksum: ", hash_new) + + if (hash_original == hash_new): + print("No changes made: Skipping file write") + else: + print("File differs") + print("Writing config to file "+target_file) + target_file_handle = open(target_file, "w") + target_file_handle.write(target_content) + target_file_handle.write("\n") + target_file_handle.flush() + target_file_handle.close() + + try: + yaml.load(target_content, Loader=yaml.SafeLoader) + print("Yaml syntax check: OK") + except Exception as e: + print("Invalid yaml syntax:", e) + + print("Finished.") + + +# Execute main function +if __name__ == '__main__': + main() diff --git a/CI/gitlab-ci/ci-master.yml b/CI/gitlab-ci/ci-master.yml new file mode 100644 index 00000000..341375c4 --- /dev/null +++ b/CI/gitlab-ci/ci-master.yml @@ -0,0 +1,37 @@ +stages: + - build + - test + - deploy + +variables: + GIT_SUBMODULE_STRATEGY: recursive + +{linux.yml} + +{mac.yml} + +{windows.yml} + +Doc-publish: + stage: deploy + only: + - master + script: "CI/ci-doc.sh" + tags: + - Linux + - stretch + +Sources: + stage: deploy + only: + - master + script: "CI/ci-source.sh" + tags: + - Linux + - stretch + artifacts: + paths: + - OpenMesh*.zip + - OpenMesh*.tar.bz2 + - OpenMesh*.tar.gz + diff --git a/CI/gitlab-ci/linux-template-build-job.yml b/CI/gitlab-ci/linux-template-build-job.yml new file mode 100644 index 00000000..4dce86a3 --- /dev/null +++ b/CI/gitlab-ci/linux-template-build-job.yml @@ -0,0 +1,14 @@ +#----------- Job Informations: +# Type: Build: {{BUILDTYPE}} +# OS: Linux +# Compiler: {{COMPILER}} +# Language: {{LANGUAGE}} + +build-{{BUILDTYPE}}-{{COMPILER}}-{{LANGUAGE}}: + stage: build + script: "CI/ci-linux-build.sh {{COMPILER}} {{LANGUAGE}} {{BUILDTYPE}}" + image: graphics.rwth-aachen.de:4567/docker/docker/docker-openmesh-container + tags: [Docker] + artifacts: + paths: + - build-{{COMPILER}}-{{LANGUAGE}}-{{BUILDTYPE}}-Vector-Checks/ diff --git a/CI/gitlab-ci/linux-template-job.yml b/CI/gitlab-ci/linux-template-job.yml new file mode 100644 index 00000000..7edb3910 --- /dev/null +++ b/CI/gitlab-ci/linux-template-job.yml @@ -0,0 +1,8 @@ +{linux-template-build-job.yml, BUILDTYPE=debug} + +{linux-template-test-job.yml, BUILDTYPE=debug} + +{linux-template-build-job.yml, BUILDTYPE=release} + +{linux-template-test-job.yml, BUILDTYPE=release} + diff --git a/CI/gitlab-ci/linux-template-test-job.yml b/CI/gitlab-ci/linux-template-test-job.yml new file mode 100644 index 00000000..efc091ab --- /dev/null +++ b/CI/gitlab-ci/linux-template-test-job.yml @@ -0,0 +1,20 @@ +#----------- Job Informations: +# Type: Test: {{BUILDTYPE}} +# OS: Linux +# Compiler: {{COMPILER}} +# Language: {{LANGUAGE}} + +test-{{BUILDTYPE}}-{{COMPILER}}-{{LANGUAGE}}: + stage: test + script: "CI/ci-linux-test.sh {{COMPILER}} {{LANGUAGE}} {{BUILDTYPE}}" + image: graphics.rwth-aachen.de:4567/docker/docker/docker-openmesh-container + tags: [Docker] + dependencies: [build-{{BUILDTYPE}}-{{COMPILER}}-{{LANGUAGE}}] + needs: [build-{{BUILDTYPE}}-{{COMPILER}}-{{LANGUAGE}}] + artifacts: + reports: + junit: + - build-{{COMPILER}}-{{LANGUAGE}}-{{BUILDTYPE}}-Vector-Checks/Unittests/report.xml + - build-{{COMPILER}}-{{LANGUAGE}}-{{BUILDTYPE}}-Vector-Checks/Unittests/report-customvec.xml + - build-{{COMPILER}}-{{LANGUAGE}}-{{BUILDTYPE}}-Vector-Checks/Unittests/report-doublevec.xml + diff --git a/CI/gitlab-ci/linux.yml b/CI/gitlab-ci/linux.yml new file mode 100644 index 00000000..1ce9de13 --- /dev/null +++ b/CI/gitlab-ci/linux.yml @@ -0,0 +1,18 @@ +# ----------------- +# Linux tasks +# ----------------- + +cppcheck: + stage: build + script: "CI/ci-cppcheck.sh" + image: graphics.rwth-aachen.de:4567/docker/docker/docker-openmesh-container + tags: [Docker] + timeout: 3h + artifacts: + paths: + - cppcheck.log + +{linux-template-job.yml, COMPILER=gcc, LANGUAGE=cpp11} +{linux-template-job.yml, COMPILER=clang, LANGUAGE=cpp11} +{linux-template-job.yml, COMPILER=gcc, LANGUAGE=cpp14} +{linux-template-job.yml, COMPILER=clang, LANGUAGE=cpp14} diff --git a/CI/gitlab-ci/mac-template-job.yml b/CI/gitlab-ci/mac-template-job.yml new file mode 100644 index 00000000..bbbcec2c --- /dev/null +++ b/CI/gitlab-ci/mac-template-job.yml @@ -0,0 +1,20 @@ +#----------- Job Informations: +# Type: Build+Test: {{BUILDTYPE}} +# OS: Mac +# Language: {{LANGUAGE}} + +macos-{{LANGUAGE}}-{{BUILDTYPE}}: + stage: build + script: "CI/ci-mac-build.sh {{LANGUAGE}} {{BUILDTYPE}} ; CI/ci-mac-test.sh {{LANGUAGE}} {{BUILDTYPE}}" + tags: + - Apple + artifacts: + paths: + - build-{{BUILDTYPE}}-{{LANGUAGE}}/*.dmg + - build-{{BUILDTYPE}}-{{LANGUAGE}}/*.tar.gz +# reports: +# junit: +# - build-{{BUILDTYPE}}-{{LANGUAGE}}/Unittests/report.xml +# - build-{{BUILDTYPE}}-{{LANGUAGE}}/Unittests/report-customvec.xml +# - build-{{BUILDTYPE}}-{{LANGUAGE}}/Unittests/report-doublevec.xml + diff --git a/CI/gitlab-ci/mac.yml b/CI/gitlab-ci/mac.yml new file mode 100644 index 00000000..208cda0c --- /dev/null +++ b/CI/gitlab-ci/mac.yml @@ -0,0 +1,10 @@ +# ----------------- +# MAC tasks +# ----------------- + +{mac-template-job.yml, BUILDTYPE=debug, LANGUAGE=cpp11} +{mac-template-job.yml, BUILDTYPE=release, LANGUAGE=cpp11} + +{mac-template-job.yml, BUILDTYPE=debug, LANGUAGE=cpp14} +{mac-template-job.yml, BUILDTYPE=release, LANGUAGE=cpp14} + diff --git a/CI/gitlab-ci/windows-template-job.yml b/CI/gitlab-ci/windows-template-job.yml new file mode 100644 index 00000000..c87d8922 --- /dev/null +++ b/CI/gitlab-ci/windows-template-job.yml @@ -0,0 +1,47 @@ +#------------- Job Informations: +# Type: Build+Test: Release +# OS: Windows +# Architecture: {{ARCHITECTURE}} +# Shared: {{SHARED}} +# VS Version: {{VSVERSION}} +# Apps: {{APPS}} + +build-{{VSVERSION}}-{{ARCHITECTURE}}-shared-{{SHARED}}-apps: + stage: build + variables: + BUILD_PLATFORM: "{{VSVERSION}}" + ARCHITECTURE: "{{ARCHITECTURE}}" + SHARED: "{{SHARED}}" + APPS: "ON" + script: "CI\\Windows.bat" + tags: + - {{VSVERSION}} + - {{QTTAG}} + artifacts: + paths: + - build-release/*.exe + reports: + junit: + - build-release/unittests/report.xml + - build-release/unittests/report-customvec.xml + - build-release/unittests/report-doublevec.xml + +build-{{VSVERSION}}-{{ARCHITECTURE}}-shared-{{SHARED}}-no-apps: + stage: build + variables: + BUILD_PLATFORM: "{{VSVERSION}}" + ARCHITECTURE: "{{ARCHITECTURE}}" + SHARED: "{{SHARED}}" + APPS: "OFF" + script: "CI\\Windows.bat" + tags: + - {{VSVERSION}} + artifacts: + paths: + - build-release/*.exe + reports: + junit: + - build-release/unittests/report.xml + - build-release/unittests/report-customvec.xml + - build-release/unittests/report-doublevec.xml + diff --git a/CI/gitlab-ci/windows.yml b/CI/gitlab-ci/windows.yml new file mode 100644 index 00000000..0000105c --- /dev/null +++ b/CI/gitlab-ci/windows.yml @@ -0,0 +1,9 @@ +# ----------------- +# Windows tasks +# ----------------- + +{windows-template-job.yml, ARCHITECTURE=x64, SHARED=TRUE, VSVERSION=VS2017, QTTAG=Qt5101} +{windows-template-job.yml, ARCHITECTURE=x64, SHARED=FALSE, VSVERSION=VS2017, QTTAG=Qt5101} + +{windows-template-job.yml, ARCHITECTURE=x64, SHARED=TRUE, VSVERSION=VS2015, QTTAG=Qt5101} +{windows-template-job.yml, ARCHITECTURE=x64, SHARED=FALSE, VSVERSION=VS2015, QTTAG=Qt5101} diff --git a/CMakeLists.txt b/CMakeLists.txt old mode 100644 new mode 100755 index 3ff533be..d5f0d3b9 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,9 @@ -cmake_minimum_required (VERSION 2.6) +cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR) + + +# Set and enforce C++-11 flags +set( CMAKE_CXX_STANDARD_REQUIRED TRUE ) +set( CMAKE_CXX_STANDARD 11 ) enable_testing() @@ -7,6 +12,12 @@ if("${PROJECT_NAME}" STREQUAL "") project (OpenMesh) endif() +# Set AUTO UIC/MOC Policy to new for CMAKE 3.17 or higher +if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.17") + cmake_policy(SET CMP0100 NEW) +endif() + + if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "6.0" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "4.9" OR CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL "4.9") message(WARNING "Your version of GCC contains an optimizer bug. Please verify that you do not use -O3!") @@ -41,6 +52,7 @@ if(${PROJECT_NAME} MATCHES "OpenMesh") endif() include (ACGOutput) +include(ACGQt) # ======================================================================== # Definitions @@ -127,13 +139,13 @@ else() set (OPENMESH_LIBRARY_DIR "${_OPENMESH_LIBRARY_DIR}" CACHE PATH "The directory where the OpenMesh libraries can be found.") endif() -add_subdirectory (Doc) +if ( NOT DEFINED OPENMESH_DOCS ) + set( OPENMESH_DOCS true CACHE BOOL "Enable or disable building of documentation" ) +endif() -# ======================================================================== -# Include Python interface -# ======================================================================== - -add_subdirectory (src/Python) +if (OPENMESH_DOCS) + add_subdirectory (Doc) +endif() # ======================================================================== # Bundle generation (Targets exist, now configure them) @@ -144,8 +156,8 @@ if(${PROJECT_NAME} MATCHES "OpenMesh") if (WIN32 AND BUILD_APPS ) # prepare bundle generation cmake file and add a build target for it - configure_file ("${CMAKE_SOURCE_DIR}/cmake/fixbundle.cmake.win.in" - "${CMAKE_BINARY_DIR}/fixbundle.win.cmake" @ONLY IMMEDIATE) + configure_file ("${CMAKE_CURRENT_SOURCE_DIR}/cmake/fixbundle.cmake.win.in" + "${CMAKE_CURRENT_BINARY_DIR}/fixbundle.win.cmake" @ONLY IMMEDIATE) if ( NOT "${CMAKE_GENERATOR}" MATCHES "MinGW Makefiles" ) # let bundle generation depend on all targets @@ -175,6 +187,20 @@ endif() # ======================================================================== +# Generate openmesh.pc file + +set(DEST_DIR "${CMAKE_INSTALL_PREFIX}") +set(PRIVATE_LIBS "-lOpenMeshCore -lOpenMeshTools") + +configure_file("openmesh.pc.in" "${CMAKE_CURRENT_BINARY_DIR}/openmesh.pc" @ONLY) + +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/openmesh.pc DESTINATION libdata/pkgconfig) + +# generate target file + +install(EXPORT OpenMeshConfig DESTINATION share/OpenMesh/cmake) + +export(TARGETS OpenMeshCore OpenMeshTools FILE OpenMeshConfig.cmake) # display results acg_print_configure_header (OPENMESH "OpenMesh") diff --git a/Doc/Concepts/MeshItems.hh b/Doc/Concepts/MeshItems.hh index 1e1524ad..db4b8627 100644 --- a/Doc/Concepts/MeshItems.hh +++ b/Doc/Concepts/MeshItems.hh @@ -40,12 +40,7 @@ * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= diff --git a/Doc/Concepts/MeshKernel.hh b/Doc/Concepts/MeshKernel.hh index 253a5cd3..e81175c1 100644 --- a/Doc/Concepts/MeshKernel.hh +++ b/Doc/Concepts/MeshKernel.hh @@ -40,14 +40,6 @@ * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ - - //============================================================================= // // Kernel Concept diff --git a/Doc/Examples/python_tutorial.py b/Doc/Examples/python_tutorial.py deleted file mode 100644 index c43420cf..00000000 --- a/Doc/Examples/python_tutorial.py +++ /dev/null @@ -1,158 +0,0 @@ -################################################## -# Getting Started -################################################## - -from openmesh import * - -mesh = TriMesh() - - -################################################## -# Adding Items to a Mesh -################################################## - -# add a a couple of vertices to the mesh -vh0 = mesh.add_vertex(TriMesh.Point(0, 1, 0)) -vh1 = mesh.add_vertex(TriMesh.Point(1, 0, 0)) -vh2 = mesh.add_vertex(TriMesh.Point(2, 1, 0)) -vh3 = mesh.add_vertex(TriMesh.Point(0,-1, 0)) -vh4 = mesh.add_vertex(TriMesh.Point(2,-1, 0)) - -# add a couple of faces to the mesh -fh0 = mesh.add_face(vh0, vh1, vh2) -fh1 = mesh.add_face(vh1, vh3, vh4) -fh2 = mesh.add_face(vh0, vh3, vh1) - -# add another face to the mesh, this time using a list -vh_list = [vh2, vh1, vh4] -fh3 = mesh.add_face(vh_list) - -# 0 ==== 2 -# |\ 0 /| -# | \ / | -# |2 1 3| -# | / \ | -# |/ 1 \| -# 3 ==== 4 - - -################################################## -# Iterators -################################################## - -# iterate over all vertices -for vh in mesh.vertices(): - print vh.idx() - -# iterate over all halfedges -for heh in mesh.halfedges(): - print heh.idx() - -# iterate over all edges -for eh in mesh.edges(): - print eh.idx() - -# iterate over all faces -for fh in mesh.faces(): - print fh.idx() - - -################################################## -# Circulators -################################################## - -# iterate over all neighboring vertices -for vh in mesh.vv(vh1): - print vh.idx() - -# iterate over all incoming halfedges -for heh in mesh.vih(vh1): - print heh.idx() - -# iterate over all outgoing halfedges -for heh in mesh.voh(vh1): - print heh.idx() - -# iterate over all adjacent edges -for eh in mesh.ve(vh1): - print eh.idx() - -# iterate over all adjacent faces -for fh in mesh.vf(vh1): - print fh.idx() - -# iterate over the face's vertices -for vh in mesh.fv(fh0): - print vh.idx() - -# iterate over the face's halfedges -for heh in mesh.fh(fh0): - print heh.idx() - -# iterate over the face's edges -for eh in mesh.fe(fh0): - print eh.idx() - -# iterate over all edge-neighboring faces -for fh in mesh.ff(fh0): - print fh.idx() - - -################################################## -# Properties -################################################## - -prop_handle = VPropHandle() -mesh.add_property(prop_handle, "cogs") - -for vh in mesh.vertices(): - cog = TriMesh.Point(0,0,0) - valence = 0 - for neighbor in mesh.vv(vh): - cog += mesh.point(neighbor) - valence += 1 - mesh.set_property(prop_handle, vh, cog / valence) - -mesh.remove_property(prop_handle) - - -################################################## -# Property Managers -################################################## - -prop_man = VPropertyManager(mesh, "cogs") - -prop_man.set_range(mesh.vertices(), TriMesh.Point(0,0,0)) - -for vh in mesh.vertices(): - valence = 0 - for neighbor in mesh.vv(vh): - prop_man[vh] += mesh.point(neighbor) - valence += 1 - prop_man[vh] /= valence - - -################################################## -# I/O -################################################## - -mesh = TriMesh() - -read_mesh(mesh, "bunny.obj") -# modify mesh ... -write_mesh(mesh, "bunny.obj") - - -mesh = TriMesh() -mesh.request_halfedge_normals() -mesh.request_vertex_normals() - -options = Options() -options += Options.VertexNormal - -result = read_mesh(mesh, "bunny.obj", options) - -if result: - print "everything worked" -else: - print "something went wrong" diff --git a/Doc/Tutorial/01-build_cube/build_cube.cc b/Doc/Tutorial/01-build_cube/build_cube.cc index 5c8d17e6..9bbd93a6 100644 --- a/Doc/Tutorial/01-build_cube/build_cube.cc +++ b/Doc/Tutorial/01-build_cube/build_cube.cc @@ -39,13 +39,6 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ - #include // -------------------- OpenMesh diff --git a/Doc/Tutorial/03-properties/smooth.cc b/Doc/Tutorial/03-properties/smooth.cc index 8756c492..41d7ab60 100644 --- a/Doc/Tutorial/03-properties/smooth.cc +++ b/Doc/Tutorial/03-properties/smooth.cc @@ -1,74 +1,57 @@ +#include +#include +#include + #include #include -// -------------------- -#include -#include -typedef OpenMesh::TriMesh_ArrayKernelT<> MyMesh; +using MyMesh = OpenMesh::TriMesh; - -int main(int argc, char **argv) +int main(int argc, char** argv) { - MyMesh mesh; - - - // check command line options - if (argc != 4) - { - std::cerr << "Usage: " << argv[0] << " #iterations infile outfile\n"; - return 1; - } - - - - // read mesh from stdin - if ( ! OpenMesh::IO::read_mesh(mesh, argv[2]) ) - { - std::cerr << "Error: Cannot read mesh from " << argv[2] << std::endl; - return 1; - } - - - - // this vertex property stores the computed centers of gravity - OpenMesh::VPropHandleT cogs; - mesh.add_property(cogs); - - // smoothing mesh argv[1] times - MyMesh::VertexIter v_it, v_end(mesh.vertices_end()); - MyMesh::VertexVertexIter vv_it; - MyMesh::Point cog; - MyMesh::Scalar valence; - unsigned int i, N(atoi(argv[1])); - - - for (i=0; i < N; ++i) - { - for (v_it=mesh.vertices_begin(); v_it!=v_end; ++v_it) - { - mesh.property(cogs,*v_it).vectorize(0.0f); - valence = 0.0; - - for (vv_it=mesh.vv_iter( *v_it ); vv_it; ++vv_it) - { - mesh.property(cogs,*v_it) += mesh.point( *vv_it ); - ++valence; - } - mesh.property(cogs,*v_it) /= valence; + // Read command line options + MyMesh mesh; + if (argc != 4) { + std::cerr << "Usage: " << argv[0] << " #iterations infile outfile" << std::endl; + return 1; } + const int iterations = argv[1]; + const std::string infile = argv[2]; + const std::string outfile = argv[3]; - for (v_it=mesh.vertices_begin(); v_it!=v_end; ++v_it) - if ( !mesh.is_boundary( *v_it ) ) - mesh.set_point( *v_it, mesh.property(cogs,*v_it) ); - } + // Read mesh file + if (!OpenMesh::IO::read_mesh(mesh, infile)) { + std::cerr << "Error: Cannot read mesh from " << infile << std::endl; + return 1; + } + { + // Add a vertex property storing the computed centers of gravity + auto cog = OpenMesh::VProp(mesh); - // write mesh to stdout - if ( ! OpenMesh::IO::write_mesh(mesh, argv[3]) ) - { - std::cerr << "Error: cannot write mesh to " << argv[3] << std::endl; - return 1; - } - - return 0; + // Smooth the mesh several times + for (int i = 0; i < iterations; ++i) { + // Iterate over all vertices to compute centers of gravity + for (const auto& vh : mesh.vertices()) { + cog[vh] = {0,0,0}; + int valence = 0; + // Iterate over all 1-ring vertices around vh + for (const auto& vvh : mesh.vv_range(vh)) { + cog[vh] += mesh.point(vvh); + ++valence; + } + cog[vh] /= valence; + } + // Move all vertices to the previously computed positions + for (const auto& vh : mesh.vertices()) { + mesh.point(vh) = cog[vh]; + } + } + } // The cog vertex property is removed from the mesh at the end of this scope + + // Write mesh file + if (!OpenMesh::IO::read_mesh(mesh, outfile)) { + std::cerr << "Error: Cannot write mesh to " << outfile << std::endl; + return 1; + } } diff --git a/Doc/Tutorial/04-stl_algorithms/smooth_algo.hh b/Doc/Tutorial/04-stl_algorithms/smooth_algo.hh index b39fd82f..968cbd7b 100644 --- a/Doc/Tutorial/04-stl_algorithms/smooth_algo.hh +++ b/Doc/Tutorial/04-stl_algorithms/smooth_algo.hh @@ -13,7 +13,7 @@ public: public: // construct with a given mesh - SmootherT(Mesh& _mesh) + explicit SmootherT(Mesh& _mesh) : mesh_(_mesh) { mesh_.add_property( cog_ ); diff --git a/Doc/Tutorial/07b-delete_geometry/delete_geometry.cc b/Doc/Tutorial/07b-delete_geometry/delete_geometry.cc index f0c0ce46..caf303de 100644 --- a/Doc/Tutorial/07b-delete_geometry/delete_geometry.cc +++ b/Doc/Tutorial/07b-delete_geometry/delete_geometry.cc @@ -39,14 +39,6 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision: 736 $ * - * $Date: 2012-10-08 09:30:49 +0200 (Mo, 08. Okt 2012) $ * - * * -\*===========================================================================*/ - - #include // -------------------- OpenMesh #include diff --git a/Doc/Tutorial/09-persistence/fill_props.hh b/Doc/Tutorial/10-persistence/fill_props.hh similarity index 100% rename from Doc/Tutorial/09-persistence/fill_props.hh rename to Doc/Tutorial/10-persistence/fill_props.hh diff --git a/Doc/Tutorial/09-persistence/generate_cube.hh b/Doc/Tutorial/10-persistence/generate_cube.hh similarity index 100% rename from Doc/Tutorial/09-persistence/generate_cube.hh rename to Doc/Tutorial/10-persistence/generate_cube.hh diff --git a/Doc/Tutorial/09-persistence/int2roman.cc b/Doc/Tutorial/10-persistence/int2roman.cc similarity index 100% rename from Doc/Tutorial/09-persistence/int2roman.cc rename to Doc/Tutorial/10-persistence/int2roman.cc diff --git a/Doc/Tutorial/09-persistence/int2roman.hh b/Doc/Tutorial/10-persistence/int2roman.hh similarity index 100% rename from Doc/Tutorial/09-persistence/int2roman.hh rename to Doc/Tutorial/10-persistence/int2roman.hh diff --git a/Doc/Tutorial/09-persistence/persistence.cc b/Doc/Tutorial/10-persistence/persistence.cc similarity index 100% rename from Doc/Tutorial/09-persistence/persistence.cc rename to Doc/Tutorial/10-persistence/persistence.cc diff --git a/Doc/Tutorial/09-persistence/stats.hh b/Doc/Tutorial/10-persistence/stats.hh similarity index 100% rename from Doc/Tutorial/09-persistence/stats.hh rename to Doc/Tutorial/10-persistence/stats.hh diff --git a/Doc/Tutorial/11-smart_handles/smooth.cc b/Doc/Tutorial/11-smart_handles/smooth.cc new file mode 100644 index 00000000..b8ceb6ad --- /dev/null +++ b/Doc/Tutorial/11-smart_handles/smooth.cc @@ -0,0 +1,62 @@ + +#include +#include +#include + +#include +#include + +using MyMesh = OpenMesh::TriMesh; + +int main(int argc, char** argv) +{ + // Read command line options + MyMesh mesh; + if (argc != 4) { + std::cerr << "Usage: " << argv[0] << " #iterations infile outfile" << std::endl; + return 1; + } + const int iterations = argv[1]; + const std::string infile = argv[2]; + const std::string outfile = argv[3]; + + // Read mesh file + if (!OpenMesh::IO::read_mesh(mesh, infile)) { + std::cerr << "Error: Cannot read mesh from " << infile << std::endl; + return 1; + } + + { + // Add a vertex property storing the laplace vector + auto laplace = OpenMesh::VProp(mesh); + + // Add a vertex property storing the laplace of the laplace + auto bi_laplace = OpenMesh::VProp(mesh); + + // Get a propertymanager of the points property of the mesh to use as functor + auto points = OpenMesh::getPointsProperty(mesh); + + // Smooth the mesh several times + for (int i = 0; i < iterations; ++i) { + // Iterate over all vertices to compute laplace vector + for (const auto& vh : mesh.vertices()) + laplace(vh) = vh.vertices().avg(points) - points(vh); + + // Iterate over all vertices to compute the laplace vector of the laplace vectors + for (const auto& vh : mesh.vertices()) + bi_laplace(vh) = (vh.vertices().avg(laplace) - laplace(vh)); + + // update points by substracting the bi-laplacian damped by a factor of 0.5 + for (const auto& vh : mesh.vertices()) + points(vh) += -0.5 * bi_laplace(vh); + } + } // The laplace and update properties are removed from the mesh at the end of this scope. + + + // Write mesh file + if (!OpenMesh::IO::read_mesh(mesh, outfile)) { + std::cerr << "Error: Cannot write mesh to " << outfile << std::endl; + return 1; + } +} + diff --git a/Doc/changelog.docu b/Doc/changelog.docu index d3021a7a..da6b4742 100644 --- a/Doc/changelog.docu +++ b/Doc/changelog.docu @@ -6,11 +6,159 @@ -7.0 (?/?/?) + +9.0 (?/?/?) + +Breaking Changes +
    +
  • Dropped 32-bit Windows continuous integration and artifact builds (This does not mean that OpenMesh will not build and work on 32-bit, but we don't explicitly test and guarantee it anymore).
  • +
+ +Core +
    +
  • Add filtered range that stores reference instead of copy if the filter is not an rvalue reference
  • +
+ +Build System +
    +
  • Dropped 32-bit Windows continuous integration and artifact builds.
  • +
+ + + + +8.1 (2020/04/23) + +Breaking Changes +
    +
  • PropertyManager: PropertyManager only gives const access to the underlying mesh.
  • +
+ + +Core +
    +
  • Property System: Get rid of the OM_FORCE_STATIC_CAST defines. We use the type ids to check if the cast is valid or not. This will add more type safety.
  • +
  • Default Traits: Added DefaultTraitsDouble as a version of the default traits that uses double precision for positions and normals as well as float for colors.
  • +
  • Default Mesh Types: Added typdefs for a Triangle Mesh and a PolyMesh which use DefaultTraitsDouble and can be used as default mesh type be the user.
  • +
  • Template Programming Convenience: Added n_elements which returns the number of elements corresponding to the handle type given as template argument. Also added elements and all_elements methods returning ranges of the elements corresponding to the handle type given as template argument. See the Smart Handles Section under Tutorials in the Documentation.
  • +
  • Smart Handles: Most userfacing functions returning handles should now return smart handles instead. Smart handles know their corresponding mesh and give convenient access to mesh navigation methods. +
  • Smart Ranges: OpenMesh ranges now provide a few methods that simplify a few calculations. See documentation for more details. +
+ + +Tools +
    +
  • Subdivider: Fixed crash in Loop subdivider
  • +
  • Subdivider: Fixed crash in ModifiedButterfly subdivider
  • +
  • Decimater: Fixed ModNormalDeviationT not working for meshes with Eigen Vectors as vector type
  • +
+ + +Utils +
    +
  • Change PropertyManager::operator* to access the property value for mesh properties
  • +
  • PropertyManager: add hasProperty function
  • +
  • PropertyManager rework: The behavior of the PropertyManager has been changed, hopefully making it more usable. See tutoial. +
+ +IO +
    +
  • PLY Reader: Fix reading doubles from PLY, missing cast (Thanks to Leo Walsh for the patch)
  • +
  • PLY Reader: Some cleanup (Thanks to Morgan Leborgne for the patch)
  • +
  • PLY Reader: Support for ushort (Thanks to Morgan Leborgne for the patch)
  • +
  • OM Reader: Positions with scalar type double will be stored as doubles.
  • +
+ + +Build System +
    +
  • Generate OpenMeshConfig.cmake (Thanks to Thibault Payet for the patch)
  • +
  • Support building on FreeBSD (Thanks to Thibault Payet for the patch)
  • +
  • Fixed Qt App Problems with cmake >= 3.17
  • +
+ + + + +8.0 (2019/02/21) + +Breaking changes: +
    +
  • Don't run and test on VS2013 anymore. As VS2013 still lacks some C++11 features, we remove it from our list of supported platforms
  • +
  • (Only internally breaking change:)Get rid of the T.cc naming for template implementations. New names end with T_impl.hh. This avoids all the missing files in the IDE GUIs due to the filtered T.cc files. Also the install targets could be simplified due to this change. For OpenMesh users, this change should be transparent.
  • +
+ +Core +
    +
  • TriConnectivity: Added two functions split_edge and split_edge_copy to mask the PolyConnectivity functions of the same name (Prevents creation of valence 2 vertices on trimeshes)
  • +
  • PolyConnectivity: Fixed PolyConnectivity is_collapse_ok, missing some configurations (Thanks to Simon Flöry for the patch)
  • +
  • Connectivity type is now set at compile time
  • +
  • Added header to interface with Eigen3 vectors as the basic type (Documentation on how to use it is also integrated)
  • +
+ +IO +
    +
  • PLY Reader: Allowing the PLY reader to read custom face ( Thanks to morgan Leborgne for the patch)
  • +
  • PLY Reader: Fixed endless loop on unknown property list type
  • +
  • PLY Reader: Fix hang when reading directly from istream (Thanks to Paul Loré for the patch)
  • +
  • PLY Reader: Fix file load for ASCII PLY without a newline at the end of the file (Thanks to Mathieu Lamarre for the patch ) +
  • PLY Reader/Writer: Support for face colors (Thanks to Steve and Barb Demlow for the patch)
  • +
  • OM Writer/Reader: Update file format version to 2.0. Older files can still be read, but older OpenMesh versions cannot read new format.
  • +
  • OM Writer/Reader: Fixed inconsistent writing/reading of edge properties
  • +
  • OM Writer/Reader: Add option to store status
  • +
  • OBJ Writer: Use Fixed as stream option in OBJ writer to avoid problems with other programs reading scientific notation
  • +
+ +Tools +
    +
  • SmartTagger: Added the SmartTagger class to tag primitives (O(1) reset )
  • +
+ +Apps +
    +
  • Fixed several warnings with gcc 8
  • +
  • Removed the glut dependency
  • +
+ +Build System +
    +
  • Rename the DEPRECATED macro into OM_DEPRECATED to prevent a macro clash with Intel MKL (Thanks to Morgan Leborgne for the patch)
  • +
+ + + + + +7.1 (2018/05/29) + +IO +
    +
  • OBJ Reader: Fixed slow OBJ reader (Thanks to Etienne Danvoye for the patch)
  • +
+ +Documentation +
    +
  • Updated build instructions.
  • +
+ +Build System +
    +
  • Default to C++11 in cmake files
  • +
  • Remove old qmake project files. Unmaintained for a very long time
  • +
  • Replaced Qt finders
  • +
  • Added VS 2017 to CI builds
  • +
+ + + + + +7.0 (2018/04/19) Breaking changes
  • The minimal standard for C++ has been raised to C++11. Compilers not supporting C++11 or higher are no longer supported
  • +
  • Removed the python bindings from this project. They have migrated to a seperate project.
Core @@ -19,12 +167,17 @@
  • make all negative handles invalid, not just -1
  • Several warnings fixed (Including the checked iterators)
  • split_copy and split_edge_copy operations now also copy internal properties.
  • +
  • copy face properties in split_copy(EdgeHandle, VertexHandle)
  • fix halfedge indices in OpenMeshTrimeshCirculatorHalfedgeLoop CWAndCCWCheck
  • Fix wrong behaviour of HalfedgeLoopIterators by changing the template parameter
  • Added 1-4 triangle split funtion(splits all edges at Midpoints)
  • Boost range support (Thanks to Bastian Pranzas for the patch)
  • Made the face and edge split operations that copy properties also copy builtin properties
  • calc_sector_angle: Check for real division by zero not with epsilon that was way to large
  • +
  • Don't return invalid iterators for empty element ranges
  • +
  • Mark halfedges as deleted after collapse
  • +
  • Let default range-based for skip deleted elements and add a version that includes deleted elements
  • +
  • Moved length() by norm() to external functions. This allows us to support other vector types instead of Vec3d (e.g. via Eigen)
  • Utils @@ -56,7 +209,7 @@
  • BaseExporter: Added accessor functions for HalfEdgeHandles and faceTexCoords to base exporter and exporter template.
  • OBJ Writer: Fail if vertex color export was requested (Thanks to Manuel Massing)
  • OBJ Writer: Added functionality to store FaceTexCoords to objwriter
  • -
  • OBJ Writer: Applied fix for bad or missing vertex tex coords (Thanks to Gero Müller for the patch)
  • > +
  • OBJ Writer: Applied fix for bad or missing vertex tex coords (Thanks to Gero Müller for the patch)
  • OBJ Writer: Fix vertex texture coordinates export in OBJ writer
  • OBJ Loader: range check for vertex colors and normals in OBJ loader
  • OBJ Loader: fixed handling of negative indices in OBJ loader
  • @@ -73,14 +226,10 @@
  • Added unittest for split_edge_copy operations on Tri and PolyMeshes
  • -Python -
      -
    • fix the stripping of the python libs version string
    • -
    - General
    • Updated Logo
    • +
    • Only Issue Warning if compile Order for MeshIO.hh is violated. Check will be removed if no errors are reported.
    diff --git a/Doc/compiling.docu b/Doc/compiling.docu new file mode 100644 index 00000000..331edad5 --- /dev/null +++ b/Doc/compiling.docu @@ -0,0 +1,162 @@ +//----------------------------------------------------------------------------- + +/** \page compiling Compiling OpenMesh + +\section compilers Tested compilers + +%OpenMesh has been successfully tested for the following operating +systems / compilers. This is only a list of tested compilers. +More might be supported but are not tested. Make sure that your compiler +supports at least C++11 + + + + + + + + + + +
    Linux +gcc >= 6.3
    +clang >= 3.3
    +
    Windows +Microsoft Visual Studio 2015
    +Microsoft Visual Studio 2017
    +
    Tested MacOS X Compilers +XCode
    +
    + +\section req_libs Required libraries (Only if you want to build the included Apps) + +Install the following external libraries / frameworks if you want to use the included Applications:

    + + +
    Qt5https://www.qt.io/download

    + +\section build_systems Chosing build system + +%OpenMesh can be built using the cmake build system. +
    +
    + +\section sec_compiling_unix Unix + +\subsection linux_using_cmake Compiling OpenMesh using CMake + +In order to compile %OpenMesh, create a directory named e.g. "build" in +OpenMesh's root directory. Change to the newly created directory and type +

    + +cmake ..            ## Generates the appropriate Makefiles
    +make                ## Builds the project
    +

    + +\warning If your compiler does not support c++11 natively, you might have to enable it by changing the cmake call to:
    + cmake .. -DCMAKE_CXX_FLAGS=-std=c++98 + +You can choose the build type by using cmake with the flag
    +-DCMAKE_BUILD_TYPE=(Debug|Release) The default is: Release
    + +Other flags are:
    +-DBUILD_APPS=OFF to disable build of applications and
    +-DCMAKE_INSTALL_PREFIX=<path> to specify the install path.
    + +When calling make install cmake will install %OpenMesh into this +directory using the subdirectories lib/include/bin. + +CMake builds both shared and static under Linux. + +Everything will then be build in the Build subdirectory containing the libraries in lib and the binaries in bin. + + +There are some additional targets:
    +doc: Builds the Documentation
    +doc-install: Builds the Documentation and installs it
    +
    +\note When you link against the static libraries of OpenMesh and get the error "can not be used when making a +shared object; recompile with -fPIC" you need to add "-fPIC" to the CMAKE_CXX_FLAGS. (This is usually added automatically) + + + + + + + + +\section sec_compiling_windows Windows + +\subsection windows_using_cmake Compiling OpenMesh using CMake + +Building OpenMesh on Windows requires cmake to generate the project files for Visual Studio. + + + +
      +
    • Get Visual Studio ( 2015-2017 )
    • +
    • Extract %OpenMesh source code.
    • +
    • Get all required libraries and install them ( including headers! ).
    • +
    • Download and install cmake: www.cmake.org.
    • +
    • Start the cmake gui and open the %OpenMesh toplevel directory as source directory
    • +
    • Choose a build directory (e.g. create a directory called "build" in OpenMesh's root folder)
    • +
    • Click on configure .... If any libraries are left unconfigured, you can adjust the path manually. Rerun configure until everything is configured correctly.
      + Attention: Some build variables are only visible in advanced view mode. Select Visual Studio 9 (2008), Visual Studio 10(2010), Visual Studio 11 (2012), Visual Studio 12 (2013) (Depending on your version) as + generator.
    • +
    • Click generate to create the visual studio project files
    • +
    • You can now find a Visual Studio solution file (OpenMesh.sln) in the build directory you chose in cmake
    • +
    • Now you can build %OpenMesh from within Visual Studio using the newly created project file.
    • +
    + +
    +
    + +\section sec_compiling_macosx MacOS X + +Download and install required libraries as stated above. +You can download %OpenMesh's sources from www.openmesh.org or check out the latest repository via GIT:
    +https://www.graphics.rwth-aachen.de:9000/OpenMesh/OpenMesh.

    + +\subsection mac_using_cmake Compiling OpenMesh using CMake + +We recommend you to use CMake >= 3.7 as build system. This can also easily be installed +via MacPorts as well as the Qt >= 5.6 library which is used for some example applications +in %OpenMesh.
    +Once installed, change to %OpenMesh's root directory and create a directory +named e.g. "buildDebug" (assuming you want to build with debug symbols).
    +Then type in the following command to initially set up the build environment: +

    + +cmake ..            ## Generates the appropriate Makefiles
    +
    +
    +Note: If the build directory is not a subdirectory of %OpenMesh's root folder, replace ".." with %OpenMesh's +absolute (or relative) path. +In order to manually set specific build variables, just type: +

    + +ccmake .            ## Configure build environment
    +
    +
    +This opens the CMake configure tool. Change the CMAKE_BUILD_TYPE variable to "Release" in order to prepare build +for release configuration. Now, when everything is set up, just type: +

    + +make                ## Build %OpenMesh
    +
    +
    +And optionally: +

    + +make doc            ## Build %OpenMesh's documentation
    +
    +
    +The mac application bundle will be found under "Build" in the recently created build folder. +It automatically contains all needed shared objects (libs, fonts, textures, etc.). + +CMake builds both shared and static under MacOS X. + +**/ + + +//----------------------------------------------------------------------------- diff --git a/Doc/doxy.config.in b/Doc/doxy.config.in index 0fc26bc6..ccfecd2c 100644 --- a/Doc/doxy.config.in +++ b/Doc/doxy.config.in @@ -1,4 +1,4 @@ -# Doxyfile 1.8.8 +# Doxyfile 1.8.13 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. @@ -46,10 +46,10 @@ PROJECT_NUMBER = PROJECT_BRIEF = -# With the PROJECT_LOGO tag one can specify an logo or icon that is included in -# the documentation. The maximum height of the logo should not exceed 55 pixels -# and the maximum width should not exceed 200 pixels. Doxygen will copy the logo -# to the output directory. +# With the PROJECT_LOGO tag one can specify a logo or an icon that is included +# in the documentation. The maximum height of the logo should not exceed 55 +# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy +# the logo to the output directory. PROJECT_LOGO = @CMAKE_CURRENT_SOURCE_DIR@/images/rwth_vci_rgb.jpg @@ -60,7 +60,7 @@ PROJECT_LOGO = @CMAKE_CURRENT_SOURCE_DIR@/images/rwth_vci_rgb.jpg OUTPUT_DIRECTORY = @CMAKE_BINARY_DIR@/Build/@ACG_PROJECT_DATADIR@/Doc -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub- +# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- # directories (in 2 levels) under the output directory of each output format and # will distribute the generated files over these directories. Enabling this # option can be useful when feeding doxygen a huge amount of source files, where @@ -93,14 +93,14 @@ ALLOW_UNICODE_NAMES = NO OUTPUT_LANGUAGE = English -# If the BRIEF_MEMBER_DESC tag is set to YES doxygen will include brief member +# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member # descriptions after the members that are listed in the file and class # documentation (similar to Javadoc). Set to NO to disable this. # The default value is: YES. BRIEF_MEMBER_DESC = YES -# If the REPEAT_BRIEF tag is set to YES doxygen will prepend the brief +# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief # description of a member or function before the detailed description # # Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the @@ -135,7 +135,7 @@ ALWAYS_DETAILED_SEC = NO INLINE_INHERITED_MEMB = NO -# If the FULL_PATH_NAMES tag is set to YES doxygen will prepend the full path +# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path # before files name in the file list and in the header files. If set to NO the # shortest path that makes the file name unique will be used # The default value is: YES. @@ -207,9 +207,9 @@ MULTILINE_CPP_IS_BRIEF = NO INHERIT_DOCS = YES -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce a -# new page for each member. If set to NO, the documentation of a member will be -# part of the file/class/namespace that contains it. +# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new +# page for each member. If set to NO, the documentation of a member will be part +# of the file/class/namespace that contains it. # The default value is: NO. SEPARATE_MEMBER_PAGES = NO @@ -278,7 +278,7 @@ OPTIMIZE_OUTPUT_VHDL = NO # instance to make doxygen treat .inc files as Fortran files (default is PHP), # and .f files as C (default is Fortran), use: inc=Fortran f=C. # -# Note For files without extension you can use no_extension as a placeholder. +# Note: For files without extension you can use no_extension as a placeholder. # # Note that for custom extensions you also need to set FILE_PATTERNS otherwise # the files are not read by doxygen. @@ -295,10 +295,19 @@ EXTENSION_MAPPING = MARKDOWN_SUPPORT = YES +# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up +# to that level are automatically included in the table of contents, even if +# they do not have an id attribute. +# Note: This feature currently applies only to Markdown headings. +# Minimum value: 0, maximum value: 99, default value: 0. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +TOC_INCLUDE_HEADINGS = 0 + # When enabled doxygen tries to link words that correspond to documented # classes, or namespaces to their corresponding documentation. Such a link can -# be prevented in individual cases by by putting a % sign in front of the word -# or globally by setting AUTOLINK_SUPPORT to NO. +# be prevented in individual cases by putting a % sign in front of the word or +# globally by setting AUTOLINK_SUPPORT to NO. # The default value is: YES. AUTOLINK_SUPPORT = YES @@ -338,13 +347,20 @@ SIP_SUPPORT = NO IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first +# tag is set to YES then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. # The default value is: NO. DISTRIBUTE_GROUP_DOC = YES +# If one adds a struct or class to a group and this option is enabled, then also +# any nested class or struct is added to the same group. By default this option +# is disabled and one has to add nested compounds explicitly via \ingroup. +# The default value is: NO. + +GROUP_NESTED_COMPOUNDS = NO + # Set the SUBGROUPING tag to YES to allow class member groups of the same type # (for instance a group of public functions) to be put as a subgroup of that # type (e.g. under the Public Functions section). Set it to NO to prevent @@ -403,7 +419,7 @@ LOOKUP_CACHE_SIZE = 0 # Build related configuration options #--------------------------------------------------------------------------- -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in # documentation are documented, even if no documentation was available. Private # class members and static file members will be hidden unless the # EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. @@ -413,35 +429,35 @@ LOOKUP_CACHE_SIZE = 0 EXTRACT_ALL = NO -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class will +# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will # be included in the documentation. # The default value is: NO. EXTRACT_PRIVATE = NO -# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal +# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal # scope will be included in the documentation. # The default value is: NO. EXTRACT_PACKAGE = NO -# If the EXTRACT_STATIC tag is set to YES all static members of a file will be +# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be # included in the documentation. # The default value is: NO. EXTRACT_STATIC = NO -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined -# locally in source files will be included in the documentation. If set to NO +# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO, # only classes defined in header files are included. Does not have any effect # for Java sources. # The default value is: YES. EXTRACT_LOCAL_CLASSES = YES -# This flag is only useful for Objective-C code. When set to YES local methods, +# This flag is only useful for Objective-C code. If set to YES, local methods, # which are defined in the implementation section but not in the interface are -# included in the documentation. If set to NO only methods in the interface are +# included in the documentation. If set to NO, only methods in the interface are # included. # The default value is: NO. @@ -466,21 +482,21 @@ HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. If set -# to NO these classes will be included in the various overviews. This option has -# no effect if EXTRACT_ALL is enabled. +# to NO, these classes will be included in the various overviews. This option +# has no effect if EXTRACT_ALL is enabled. # The default value is: NO. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend -# (class|struct|union) declarations. If set to NO these declarations will be +# (class|struct|union) declarations. If set to NO, these declarations will be # included in the documentation. # The default value is: NO. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any -# documentation blocks found inside the body of a function. If set to NO these +# documentation blocks found inside the body of a function. If set to NO, these # blocks will be appended to the function's detailed documentation block. # The default value is: NO. @@ -494,7 +510,7 @@ HIDE_IN_BODY_DOCS = NO INTERNAL_DOCS = YES # If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file -# names in lower-case letters. If set to YES upper-case letters are also +# names in lower-case letters. If set to YES, upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. @@ -503,12 +519,19 @@ INTERNAL_DOCS = YES CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with -# their full class and namespace scopes in the documentation. If set to YES the +# their full class and namespace scopes in the documentation. If set to YES, the # scope will be hidden. # The default value is: NO. HIDE_SCOPE_NAMES = NO +# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will +# append additional text to a page's title, such as Class Reference. If set to +# YES the compound reference will be hidden. +# The default value is: NO. + +HIDE_COMPOUND_REFERENCE= NO + # If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of # the files that are included by a file in the documentation of that file. # The default value is: YES. @@ -536,14 +559,14 @@ INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the # (detailed) documentation of file and class members alphabetically by member -# name. If set to NO the members will appear in declaration order. +# name. If set to NO, the members will appear in declaration order. # The default value is: YES. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief # descriptions of file, namespace and class members alphabetically by member -# name. If set to NO the members will appear in declaration order. Note that +# name. If set to NO, the members will appear in declaration order. Note that # this will also influence the order of the classes in the class list. # The default value is: NO. @@ -588,27 +611,25 @@ SORT_BY_SCOPE_NAME = NO STRICT_PROTO_MATCHING = NO -# The GENERATE_TODOLIST tag can be used to enable ( YES) or disable ( NO) the -# todo list. This list is created by putting \todo commands in the -# documentation. +# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo +# list. This list is created by putting \todo commands in the documentation. # The default value is: YES. GENERATE_TODOLIST = YES -# The GENERATE_TESTLIST tag can be used to enable ( YES) or disable ( NO) the -# test list. This list is created by putting \test commands in the -# documentation. +# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test +# list. This list is created by putting \test commands in the documentation. # The default value is: YES. GENERATE_TESTLIST = YES -# The GENERATE_BUGLIST tag can be used to enable ( YES) or disable ( NO) the bug +# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug # list. This list is created by putting \bug commands in the documentation. # The default value is: YES. GENERATE_BUGLIST = YES -# The GENERATE_DEPRECATEDLIST tag can be used to enable ( YES) or disable ( NO) +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) # the deprecated list. This list is created by putting \deprecated commands in # the documentation. # The default value is: YES. @@ -633,8 +654,8 @@ ENABLED_SECTIONS = OPENMESH_INTERNAL_DOC MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated at -# the bottom of the documentation of classes and structs. If set to YES the list -# will mention the files that were used to generate the documentation. +# the bottom of the documentation of classes and structs. If set to YES, the +# list will mention the files that were used to generate the documentation. # The default value is: YES. SHOW_USED_FILES = YES @@ -698,7 +719,7 @@ CITE_BIB_FILES = QUIET = YES # The WARNINGS tag can be used to turn on/off the warning messages that are -# generated to standard error ( stderr) by doxygen. If WARNINGS is set to YES +# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES # this implies that the warnings are on. # # Tip: Turn warnings on while writing the documentation. @@ -706,7 +727,7 @@ QUIET = YES WARNINGS = YES -# If the WARN_IF_UNDOCUMENTED tag is set to YES, then doxygen will generate +# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate # warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag # will automatically be disabled. # The default value is: YES. @@ -723,12 +744,18 @@ WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that # are documented, but have no documentation for their parameters or return -# value. If set to NO doxygen will only warn about wrong or incomplete parameter -# documentation, but not about the absence of documentation. +# value. If set to NO, doxygen will only warn about wrong or incomplete +# parameter documentation, but not about the absence of documentation. # The default value is: NO. WARN_NO_PARAMDOC = NO +# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when +# a warning is encountered. +# The default value is: NO. + +WARN_AS_ERROR = NO + # The WARN_FORMAT tag determines the format of the warning messages that doxygen # can produce. The string should contain the $file, $line, and $text tags, which # will be replaced by the file and line number from which the warning originated @@ -752,7 +779,7 @@ WARN_LOGFILE = # The INPUT tag is used to specify the files and/or directories that contain # documented source files. You may enter file names like myfile.cpp or # directories like /usr/src/myproject. Separate the files or directories with -# spaces. +# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # Note: If this tag is empty the current directory is searched. INPUT = @CMAKE_CURRENT_SOURCE_DIR@/.. @@ -768,12 +795,17 @@ INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and -# *.h) to filter out the source-files in the directories. If left blank the -# following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii, -# *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp, -# *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown, -# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, -# *.qsf, *.as and *.js. +# *.h) to filter out the source-files in the directories. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# read by doxygen. +# +# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, +# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, +# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, +# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, +# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf and *.qsf. FILE_PATTERNS = *.cc \ *.hh \ @@ -871,6 +903,10 @@ IMAGE_PATH = @CMAKE_CURRENT_SOURCE_DIR@/images # Note that the filter must not add or remove lines; it is applied before the # code is scanned, but not when the output code is generated. If lines are added # or removed, the anchors will not be placed correctly. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. INPUT_FILTER = @@ -880,11 +916,15 @@ INPUT_FILTER = # (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how # filters are used. If the FILTER_PATTERNS tag is empty or if none of the # patterns match the file name, INPUT_FILTER is applied. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER ) will also be used to filter the input files that are used for +# INPUT_FILTER) will also be used to filter the input files that are used for # producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). # The default value is: NO. @@ -944,7 +984,7 @@ REFERENCED_BY_RELATION = NO REFERENCES_RELATION = NO # If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set -# to YES, then the hyperlinks from functions in REFERENCES_RELATION and +# to YES then the hyperlinks from functions in REFERENCES_RELATION and # REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will # link to the documentation. # The default value is: YES. @@ -991,13 +1031,13 @@ USE_HTAGS = NO VERBATIM_HEADERS = YES -# If the CLANG_ASSISTED_PARSING tag is set to YES, then doxygen will use the +# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the # clang parser (see: http://clang.llvm.org/) for more accurate parsing at the # cost of reduced performance. This can be particularly helpful with template # rich C++ code for which doxygen's built-in parser lacks the necessary type # information. # Note: The availability of this option depends on whether or not doxygen was -# compiled with the --with-libclang option. +# generated with the -Duse-libclang=ON option for CMake. # The default value is: NO. CLANG_ASSISTED_PARSING = NO @@ -1040,7 +1080,7 @@ IGNORE_PREFIX = # Configuration options related to the HTML output #--------------------------------------------------------------------------- -# If the GENERATE_HTML tag is set to YES doxygen will generate HTML output +# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output # The default value is: YES. GENERATE_HTML = YES @@ -1106,10 +1146,10 @@ HTML_STYLESHEET = # cascading style sheets that are included after the standard style sheets # created by doxygen. Using this option one can overrule certain style aspects. # This is preferred over using HTML_STYLESHEET since it does not replace the -# standard style sheet and is therefor more robust against future updates. +# standard style sheet and is therefore more robust against future updates. # Doxygen will copy the style sheet files to the output directory. -# Note: The order of the extra stylesheet files is of importance (e.g. the last -# stylesheet in the list overrules the setting of the previous ones in the +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the # list). For an example see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. @@ -1126,7 +1166,7 @@ HTML_EXTRA_STYLESHEET = @CMAKE_CURRENT_SOURCE_DIR@/html/logo_align.css HTML_EXTRA_FILES = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen -# will adjust the colors in the stylesheet and background images according to +# will adjust the colors in the style sheet and background images according to # this color. Hue is specified as an angle on a colorwheel, see # http://en.wikipedia.org/wiki/Hue for more information. For instance the value # 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 @@ -1157,8 +1197,9 @@ HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting this -# to NO can help when comparing the output of multiple runs. -# The default value is: YES. +# to YES can help to show when doxygen was last run and thus if the +# documentation is up to date. +# The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_TIMESTAMP = YES @@ -1254,28 +1295,28 @@ GENERATE_HTMLHELP = NO CHM_FILE = # The HHC_LOCATION tag can be used to specify the location (absolute path -# including file name) of the HTML help compiler ( hhc.exe). If non-empty +# including file name) of the HTML help compiler (hhc.exe). If non-empty, # doxygen will try to run the HTML help compiler on the generated index.hhp. # The file has to be specified with full path. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. HHC_LOCATION = -# The GENERATE_CHI flag controls if a separate .chi index file is generated ( -# YES) or that it should be included in the master .chm file ( NO). +# The GENERATE_CHI flag controls if a separate .chi index file is generated +# (YES) or that it should be included in the master .chm file (NO). # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. GENERATE_CHI = NO -# The CHM_INDEX_ENCODING is used to encode HtmlHelp index ( hhk), content ( hhc) +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) # and project file content. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. CHM_INDEX_ENCODING = -# The BINARY_TOC flag controls whether a binary table of contents is generated ( -# YES) or a normal table of contents ( NO) in the .chm file. Furthermore it +# The BINARY_TOC flag controls whether a binary table of contents is generated +# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it # enables the Previous and Next buttons. # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. @@ -1389,7 +1430,7 @@ DISABLE_INDEX = NO # index structure (just like the one that is generated for HTML Help). For this # to work a browser that supports JavaScript, DHTML, CSS and frames is required # (i.e. any modern browser). Windows users are probably better off using the -# HTML help feature. Via custom stylesheets (see HTML_EXTRA_STYLESHEET) one can +# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can # further fine-tune the look of the index. As an example, the default style # sheet generated by doxygen has an example that shows how to put an image at # the root of the tree instead of the PROJECT_NAME. Since the tree basically has @@ -1417,7 +1458,7 @@ ENUM_VALUES_PER_LINE = 4 TREEVIEW_WIDTH = 300 -# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open links to +# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to # external symbols imported via tag files in a separate window. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. @@ -1446,7 +1487,7 @@ FORMULA_TRANSPARENT = YES # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see # http://www.mathjax.org) which uses client side Javascript for the rendering -# instead of using prerendered bitmaps. Use this if you do not have LaTeX +# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX # installed or if you want to formulas look prettier in the HTML output. When # enabled you may also need to install MathJax separately and configure the path # to it using the MATHJAX_RELPATH option. @@ -1532,7 +1573,7 @@ SERVER_BASED_SEARCH = NO # external search engine pointed to by the SEARCHENGINE_URL option to obtain the # search results. # -# Doxygen ships with an example indexer ( doxyindexer) and search engine +# Doxygen ships with an example indexer (doxyindexer) and search engine # (doxysearch.cgi) which are based on the open source search engine library # Xapian (see: http://xapian.org/). # @@ -1545,7 +1586,7 @@ EXTERNAL_SEARCH = NO # The SEARCHENGINE_URL should point to a search engine hosted by a web server # which will return the search results when EXTERNAL_SEARCH is enabled. # -# Doxygen ships with an example indexer ( doxyindexer) and search engine +# Doxygen ships with an example indexer (doxyindexer) and search engine # (doxysearch.cgi) which are based on the open source search engine library # Xapian (see: http://xapian.org/). See the section "External Indexing and # Searching" for details. @@ -1583,7 +1624,7 @@ EXTRA_SEARCH_MAPPINGS = # Configuration options related to the LaTeX output #--------------------------------------------------------------------------- -# If the GENERATE_LATEX tag is set to YES doxygen will generate LaTeX output. +# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output. # The default value is: YES. GENERATE_LATEX = NO @@ -1614,7 +1655,7 @@ LATEX_CMD_NAME = latex MAKEINDEX_CMD_NAME = makeindex -# If the COMPACT_LATEX tag is set to YES doxygen generates more compact LaTeX +# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX # documents. This may be useful for small projects and may help to save some # trees in general. # The default value is: NO. @@ -1632,9 +1673,12 @@ COMPACT_LATEX = NO PAPER_TYPE = a4wide # The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names -# that should be included in the LaTeX output. To get the times font for -# instance you can specify -# EXTRA_PACKAGES=times +# that should be included in the LaTeX output. The package can be specified just +# by its name or with the correct syntax as to be used with the LaTeX +# \usepackage command. To get the times font for instance you can specify : +# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times} +# To use the option intlimits with the amsmath package you can specify: +# EXTRA_PACKAGES=[intlimits]{amsmath} # If left blank no extra packages will be included. # This tag requires that the tag GENERATE_LATEX is set to YES. @@ -1649,9 +1693,9 @@ EXTRA_PACKAGES = # Note: Only use a user-defined header if you know what you are doing! The # following commands have a special meaning inside the header: $title, # $datetime, $date, $doxygenversion, $projectname, $projectnumber, -# $projectbrief, $projectlogo. Doxygen will replace $title with the empy string, -# for the replacement values of the other commands the user is refered to -# HTML_HEADER. +# $projectbrief, $projectlogo. Doxygen will replace $title with the empty +# string, for the replacement values of the other commands the user is referred +# to HTML_HEADER. # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_HEADER = @@ -1667,6 +1711,17 @@ LATEX_HEADER = LATEX_FOOTER = +# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# LaTeX style sheets that are included after the standard style sheets created +# by doxygen. Using this option one can overrule certain style aspects. Doxygen +# will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_EXTRA_STYLESHEET = + # The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the LATEX_OUTPUT output # directory. Note that the files will be copied as-is; there are no commands or @@ -1685,7 +1740,7 @@ LATEX_EXTRA_FILES = PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate -# the PDF file directly from the LaTeX files. Set this option to YES to get a +# the PDF file directly from the LaTeX files. Set this option to YES, to get a # higher quality PDF documentation. # The default value is: YES. # This tag requires that the tag GENERATE_LATEX is set to YES. @@ -1726,11 +1781,19 @@ LATEX_SOURCE_CODE = NO LATEX_BIB_STYLE = plain +# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated +# page will contain the date and time when the page was generated. Setting this +# to NO can help when comparing the output of multiple runs. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_TIMESTAMP = NO + #--------------------------------------------------------------------------- # Configuration options related to the RTF output #--------------------------------------------------------------------------- -# If the GENERATE_RTF tag is set to YES doxygen will generate RTF output. The +# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The # RTF output is optimized for Word 97 and may not look too pretty with other RTF # readers/editors. # The default value is: NO. @@ -1745,7 +1808,7 @@ GENERATE_RTF = NO RTF_OUTPUT = rtf -# If the COMPACT_RTF tag is set to YES doxygen generates more compact RTF +# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF # documents. This may be useful for small projects and may help to save some # trees in general. # The default value is: NO. @@ -1782,11 +1845,21 @@ RTF_STYLESHEET_FILE = RTF_EXTENSIONS_FILE = +# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code +# with syntax highlighting in the RTF output. +# +# Note that which sources are shown also depends on other settings such as +# SOURCE_BROWSER. +# The default value is: NO. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_SOURCE_CODE = NO + #--------------------------------------------------------------------------- # Configuration options related to the man page output #--------------------------------------------------------------------------- -# If the GENERATE_MAN tag is set to YES doxygen will generate man pages for +# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for # classes and files. # The default value is: NO. @@ -1830,7 +1903,7 @@ MAN_LINKS = NO # Configuration options related to the XML output #--------------------------------------------------------------------------- -# If the GENERATE_XML tag is set to YES doxygen will generate an XML file that +# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that # captures the structure of the code including all documentation. # The default value is: NO. @@ -1844,7 +1917,7 @@ GENERATE_XML = NO XML_OUTPUT = xml -# If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program +# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program # listings (including syntax highlighting and cross-referencing information) to # the XML output. Note that enabling this will significantly increase the size # of the XML output. @@ -1857,7 +1930,7 @@ XML_PROGRAMLISTING = YES # Configuration options related to the DOCBOOK output #--------------------------------------------------------------------------- -# If the GENERATE_DOCBOOK tag is set to YES doxygen will generate Docbook files +# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files # that can be used to generate PDF. # The default value is: NO. @@ -1871,7 +1944,7 @@ GENERATE_DOCBOOK = NO DOCBOOK_OUTPUT = docbook -# If the DOCBOOK_PROGRAMLISTING tag is set to YES doxygen will include the +# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the # program listings (including syntax highlighting and cross-referencing # information) to the DOCBOOK output. Note that enabling this will significantly # increase the size of the DOCBOOK output. @@ -1884,10 +1957,10 @@ DOCBOOK_PROGRAMLISTING = NO # Configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- -# If the GENERATE_AUTOGEN_DEF tag is set to YES doxygen will generate an AutoGen -# Definitions (see http://autogen.sf.net) file that captures the structure of -# the code including all documentation. Note that this feature is still -# experimental and incomplete at the moment. +# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an +# AutoGen Definitions (see http://autogen.sf.net) file that captures the +# structure of the code including all documentation. Note that this feature is +# still experimental and incomplete at the moment. # The default value is: NO. GENERATE_AUTOGEN_DEF = NO @@ -1896,7 +1969,7 @@ GENERATE_AUTOGEN_DEF = NO # Configuration options related to the Perl module output #--------------------------------------------------------------------------- -# If the GENERATE_PERLMOD tag is set to YES doxygen will generate a Perl module +# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module # file that captures the structure of the code including all documentation. # # Note that this feature is still experimental and incomplete at the moment. @@ -1904,7 +1977,7 @@ GENERATE_AUTOGEN_DEF = NO GENERATE_PERLMOD = NO -# If the PERLMOD_LATEX tag is set to YES doxygen will generate the necessary +# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary # Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI # output from the Perl module output. # The default value is: NO. @@ -1912,9 +1985,9 @@ GENERATE_PERLMOD = NO PERLMOD_LATEX = NO -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be nicely +# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely # formatted so it can be parsed by a human reader. This is useful if you want to -# understand what is going on. On the other hand, if this tag is set to NO the +# understand what is going on. On the other hand, if this tag is set to NO, the # size of the Perl module output will be much smaller and Perl will parse it # just the same. # The default value is: YES. @@ -1934,14 +2007,14 @@ PERLMOD_MAKEVAR_PREFIX = # Configuration options related to the preprocessor #--------------------------------------------------------------------------- -# If the ENABLE_PREPROCESSING tag is set to YES doxygen will evaluate all +# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all # C-preprocessor directives found in the sources and include files. # The default value is: YES. ENABLE_PREPROCESSING = YES -# If the MACRO_EXPANSION tag is set to YES doxygen will expand all macro names -# in the source code. If set to NO only conditional compilation will be +# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names +# in the source code. If set to NO, only conditional compilation will be # performed. Macro expansion can be done in a controlled way by setting # EXPAND_ONLY_PREDEF to YES. # The default value is: NO. @@ -1957,7 +2030,7 @@ MACRO_EXPANSION = YES EXPAND_ONLY_PREDEF = NO -# If the SEARCH_INCLUDES tag is set to YES the includes files in the +# If the SEARCH_INCLUDES tag is set to YES, the include files in the # INCLUDE_PATH will be searched if a #include is found. # The default value is: YES. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. @@ -2036,20 +2109,21 @@ TAGFILES = GENERATE_TAGFILE = -# If the ALLEXTERNALS tag is set to YES all external class will be listed in the -# class index. If set to NO only the inherited external classes will be listed. +# If the ALLEXTERNALS tag is set to YES, all external class will be listed in +# the class index. If set to NO, only the inherited external classes will be +# listed. # The default value is: NO. ALLEXTERNALS = NO -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed in -# the modules index. If set to NO, only the current project's groups will be +# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will be # listed. # The default value is: YES. EXTERNAL_GROUPS = YES -# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed in +# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in # the related pages index. If set to NO, only the current project's pages will # be listed. # The default value is: YES. @@ -2066,7 +2140,7 @@ PERL_PATH = /usr/bin/perl # Configuration options related to the dot tool #--------------------------------------------------------------------------- -# If the CLASS_DIAGRAMS tag is set to YES doxygen will generate a class diagram +# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram # (in HTML and LaTeX) for classes with base or super classes. Setting the tag to # NO turns the diagrams off. Note that this option also works with HAVE_DOT # disabled, but it is recommended to install and use dot, since it yields more @@ -2091,7 +2165,7 @@ MSCGEN_PATH = DIA_PATH = -# If set to YES, the inheritance and collaboration graphs will hide inheritance +# If set to YES the inheritance and collaboration graphs will hide inheritance # and usage relations if the target is undocumented or is not a class. # The default value is: YES. @@ -2164,7 +2238,7 @@ COLLABORATION_GRAPH = YES GROUP_GRAPHS = YES -# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. # The default value is: NO. @@ -2216,7 +2290,8 @@ INCLUDED_BY_GRAPH = YES # # Note that enabling this option will significantly increase the time of a run. # So in most cases it will be better to enable call graphs for selected -# functions only using the \callgraph command. +# functions only using the \callgraph command. Disabling a call graph can be +# accomplished by means of the command \hidecallgraph. # The default value is: NO. # This tag requires that the tag HAVE_DOT is set to YES. @@ -2227,7 +2302,8 @@ CALL_GRAPH = NO # # Note that enabling this option will significantly increase the time of a run. # So in most cases it will be better to enable caller graphs for selected -# functions only using the \callergraph command. +# functions only using the \callergraph command. Disabling a caller graph can be +# accomplished by means of the command \hidecallergraph. # The default value is: NO. # This tag requires that the tag HAVE_DOT is set to YES. @@ -2250,13 +2326,17 @@ GRAPHICAL_HIERARCHY = YES DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. +# generated by dot. For an explanation of the image formats see the section +# output formats in the documentation of the dot tool (Graphviz (see: +# http://www.graphviz.org/)). # Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order # to make the SVG files visible in IE 9+ (other browsers do not have this # requirement). # Possible values are: png, png:cairo, png:cairo:cairo, png:cairo:gd, png:gd, # png:gd:gd, jpg, jpg:cairo, jpg:cairo:gd, jpg:gd, jpg:gd:gd, gif, gif:cairo, -# gif:cairo:gd, gif:gd, gif:gd:gd and svg. +# gif:cairo:gd, gif:gd, gif:gd:gd, svg, png:gd, png:gd:gd, png:cairo, +# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and +# png:gdiplus:gdiplus. # The default value is: png. # This tag requires that the tag HAVE_DOT is set to YES. @@ -2304,10 +2384,19 @@ DIAFILE_DIRS = # PlantUML is not used or called during a preprocessing step. Doxygen will # generate a warning when it encounters a \startuml command in this case and # will not generate output for the diagram. -# This tag requires that the tag HAVE_DOT is set to YES. PLANTUML_JAR_PATH = +# When using plantuml, the PLANTUML_CFG_FILE tag can be used to specify a +# configuration file for plantuml. + +PLANTUML_CFG_FILE = + +# When using plantuml, the specified paths are searched for files specified by +# the !include statement in a plantuml block. + +PLANTUML_INCLUDE_PATH = + # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes # that will be shown in the graph. If the number of nodes in a graph becomes # larger than this value, doxygen will truncate the graph, which is visualized @@ -2344,7 +2433,7 @@ MAX_DOT_GRAPH_DEPTH = 0 DOT_TRANSPARENT = NO -# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) support # this, this feature is disabled by default. @@ -2361,7 +2450,7 @@ DOT_MULTI_TARGETS = YES GENERATE_LEGEND = YES -# If the DOT_CLEANUP tag is set to YES doxygen will remove the intermediate dot +# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot # files that are used to generate the various graphs. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. diff --git a/Doc/mainpage.docu b/Doc/mainpage.docu index ad8fa8e9..63bfee8c 100644 --- a/Doc/mainpage.docu +++ b/Doc/mainpage.docu @@ -24,6 +24,10 @@ Here you can find information on how to build projects using the %OpenMesh libra as well as further information on mesh handling in %OpenMesh. The tutorials explain how to use %OpenMesh by demonstrating real code examples. +\section openmesh-python OpenMesh Python Bindings +We also provide python bindings for %OpenMesh. You can find them here:
    +https://www.graphics.rwth-aachen.de:9000/OpenMesh/openmesh-python + \section iov Building OpenMesh In this section all necessary information on how to build projects using %OpenMesh is given. @@ -78,20 +82,14 @@ repeatedly replacing each vertex' position by the center of gravity \li \ref tutorial_02 \li \ref tutorial_03 \li \ref tutorial_04 +\li \ref tutorial_11 \li \ref tutorial_05 \li \ref tutorial_06 \li \ref tutorial_07 \li \ref tutorial_07b \li \ref tutorial_08 \li \ref tutorial_09 - -

    - -\section python_and_om OpenMesh Python interface -OpenMesh itself is written in C++. We also provide a python interface -to use OpenMesh. A detailed description of the interface can be found -in the following tutorial: -\li \subpage python_tutorial +\li \ref tutorial_10

    @@ -113,6 +111,7 @@ in the following tutorial: \li \subpage mesh_operations \li \subpage mesh_hierarchy \li \subpage mesh_type +\li \subpage mesh_eigen \page additional_information Additional Information on OpenMesh diff --git a/Doc/mesh.docu b/Doc/mesh.docu index 488e06da..a506f300 100644 --- a/Doc/mesh.docu +++ b/Doc/mesh.docu @@ -555,6 +555,45 @@ curvature, i.e. vertex color. That's it. +//----------------------------------------------------------------------------- + +/** \page mesh_eigen Specifying an OpenMesh using Eigen3 vectors + +This section will show how to build your own custom mesh type using +Eigen3 vectors for points, normals or other entities. + +First of all you need to include the Eigen header shipped with OpenMesh: +\code +#include +\endcode + +This header contains the external functions and vector traits used by +OpenMesh. + +Afterwards you can specify your mesh: + +\code +struct EigenTraits : OpenMesh::DefaultTraits { + using Point = Eigen::Vector3d; + using Normal = Eigen::Vector3d; + + using TexCoord2D = Eigen::Vector2d; +}; + +using EigenTriMesh = OpenMesh::TriMesh_ArrayKernelT; + +EigenTriMesh mesh; + +\endcode + +Now you can use mesh as any other OpenMesh while using Eigen vectors +as the underlying data type. + +\note OpenMesh uses stl vectors for storing its data. This might lead to errors + regarding memory alignment with sse instructions: + http://eigen.tuxfamily.org/dox/group__TopicStlContainers.html + You might need to define -DEIGEN_DONT_VECTORIZE + */ diff --git a/Doc/misc.docu b/Doc/misc.docu index 864127ef..b960c382 100644 --- a/Doc/misc.docu +++ b/Doc/misc.docu @@ -7,6 +7,7 @@ The following naming conventions are used for the %OpenMesh code: Files: \li \c MyClass.cc for C++-Implementation of class \c MyClass + \li \c MyClassT_impl.hh for Header only C++-Implementation of template class \c MyClass \li \c MyClass.hh for C++-Header of class \c MyClass Classes: @@ -27,167 +28,4 @@ The following naming conventions are used for the %OpenMesh code: **/ - -//----------------------------------------------------------------------------- - - -/** \page compiling Compiling OpenMesh - -\section compilers Tested compilers - -%OpenMesh has been successfully tested for the following operating -systems / compilers. This is only a list of tested compilers. More might be supported but are not tested. - - - - - - - - - - -
    Linux -gcc 4.6.x
    -gcc 4.7.x
    -gcc 4.8.x
    -gcc 4.9.x
    -clang 3.3
    -clang 3.4
    -
    Windows -Microsoft Visual Studio 2008
    -Microsoft Visual Studio 2010
    -Microsoft Visual Studio 2012
    -Microsoft Visual Studio 2013
    -Microsoft Visual Studio 2015
    -
    Tested MacOS X Compilers -XCode 4.3
    -XCode 4.4
    -XCode 4.5
    -XCode 5.1.1
    -Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)
    -
    - -\section req_libs Required libraries (Only for included Apps) - -Install the following external libraries / frameworks if you want to use the included Applications:

    - - -
    Qt4/Qt5http://qt-project.org/downloads

    - -\section build_systems Chosing build system - -%OpenMesh can be built using the cmake build system. -
    -
    - -\section sec_compiling_unix Unix - -\subsection linux_using_cmake Compiling OpenMesh using CMake - -In order to compile %OpenMesh, create a directory named e.g. "build" in -OpenMesh's root directory. Change to the newly created directory and type -

    - -cmake ..            ## Generates the appropriate Makefiles
    -make                ## Builds the project
    -

    -You can choose the build type by using cmake with the flag
    --DCMAKE_BUILD_TYPE=(Debug|Release)
    -The default is: Debug -
    -Other flags are:
    --DBUILD_APPS=OFF to disable build of applications and
    --DCMAKE_INSTALL_PREFIX=<path> to specify the install path. -
    -When calling make install cmake will install %OpenMesh into this -directory using the subdirectories lib/include/bin. - -CMake builds both shared and static under Linux. - -Everything will then be build in the Build subdirectory containing the libraries in lib and the binaries in bin. - -There are some additional targets:
    -doc: Builds the Documentation
    -doc-install: Builds the Documentation and installs it
    -
    -\note When you link against the static libraries of OpenMesh and get the error "can not be used when making a -shared object; recompile with -fPIC" you need to add "-fPIC" to the CMAKE_CXX_FLAGS. (This is usually added automatically) - -\section sec_compiling_windows Windows - -\subsection windows_using_cmake Compiling OpenMesh using CMake - -If you want to use cmake to build your Visual Studio 2008 solution file,
    -download and install CMake from www.cmake.org.
    -(Note: This is not mandatory since there are already VS2008 solution files included in %OpenMesh).

    -
      -
    • Get Visual Studio ( 2008-2013 )
    • -
    • Extract %OpenMesh source code.
    • -
    • Get all required libraries and install them ( including headers! ).
    • -
    • Get cmake for windows from http://www.cmake.org/cmake/resources/software.html
    • -
    • Start the cmake gui and open the %OpenMesh toplevel directory as source directory
    • -
    • Choose a build directory (e.g. create a directory called "build" in OpenMesh's root folder)
    • -
    • Click on configure .... If any libraries are left unconfigured, you can adjust the path manually. Rerun configure until everything is configured correctly. - Attention: Some build variables are only visible in advanced view mode. Select Visual Studio 9 (2008), Visual Studio 10(2010), Visual Studio 11 (2012), Visual Studio 12 (2013) (Depending on your version) as - generator.
    • -
    • Click generate to create the visual studio project files
    • -
    • You can now find a Visual Studio solution file (OpenMesh.sln) in the build directory you chose in cmake
    • -
    • Now you can build %OpenMesh from within Visual Studio using the newly created project file.
    • -
    - -Note: Set the CMAKE_BUILD_TYPE variable to "Release" if you want %OpenMesh to be built as release. -In Visual Studio choose "Release" in the appropriate select box and build the solution afterwards. - -
    -
    - -\section sec_compiling_macosx MacOS X - -Download and install required libraries as stated above. -You can download %OpenMesh's sources from www.openmesh.org or check out the latest repository via SVN:
    -svn co http://www.openmesh.org/svnrepo/OpenMesh/trunk %OpenMesh.

    - -\subsection mac_using_cmake Compiling OpenMesh using CMake - -We recommend you to use CMake >= 2.8 as build system. This can also easily be installed -via MacPorts as well as the Qt >= 4.7 library which is used for some example applications -in %OpenMesh.
    -Once installed, change to %OpenMesh's root directory and create a directory -named e.g. "buildDebug" (assuming you want to build with debug symbols).
    -Then type in the following command to initially set up the build environment: -

    - -cmake ..            ## Generates the appropriate Makefiles
    -
    -
    -Note: If the build directory is not a subdirectory of %OpenMesh's root folder, replace ".." with %OpenMesh's -absolute (or relative) path. -In order to manually set specific build variables, just type: -

    - -ccmake .            ## Configure build environment
    -
    -
    -This opens the CMake configure tool. Change the CMAKE_BUILD_TYPE variable to "Release" in order to prepare build -for release configuration. Now, when everything is set up, just type: -

    - -make                ## Build %OpenMesh
    -
    -
    -And optionally: -

    - -make doc            ## Build %OpenMesh's documentation
    -
    -
    -The mac application bundle will be found under "Build" in the recently created build folder. -It automatically contains all needed shared objects (libs, fonts, textures, etc.). - -CMake builds both shared and static under MacOS X. - -**/ - - //----------------------------------------------------------------------------- diff --git a/Doc/python_tutorial.docu b/Doc/python_tutorial.docu deleted file mode 100644 index 8649d4f9..00000000 --- a/Doc/python_tutorial.docu +++ /dev/null @@ -1,288 +0,0 @@ -/** \page python_tutorial Python Tutorial - -This tutorial will introduce the basic concepts behind the %OpenMesh Python -Bindings. We will cover the following topics: - -\li How to build the Python Bindings -\li How to create an empty mesh -\li How to add vertices and faces to a mesh -\li How to navigate on a mesh using iterators and circulators -\li How to add and remove custom properties -\li How to read and write meshes from files - -In addition, we will briefly discuss some of the differences between the Python -Bindings and the original C++ implementation of %OpenMesh. - - - -\section python_build Building the Python Bindings - -The Python Bindings depend on the following libraries: - -\li Python (2.7 or later) -\li Boost Python (1.54.0 or later) - -\note Make sure that your Boost Python and Python versions match, i.e. that -Boost Python was linked against the correct Python version. - -The Python Bindings are automatically built with %OpenMesh. The generated files are written to the -Build/python subdirectory of the build tree. For more information on how to build %OpenMesh see -\ref compiling. - -If CMake does not find your Python installation (or finds the wrong one) you can -explicitly specify an installation by setting the following variables: - -\verbatim -PYTHON_LIBRARY - Path to the python library -PYTHON_INCLUDE_DIR - Path to where Python.h is found -\endverbatim - -Similarly, if CMake does not find your Boost Python installation, set the -following variables: - -\verbatim -BOOST_ROOT - Preferred installation prefix -BOOST_INCLUDEDIR - Preferred include directory e.g. /include -BOOST_LIBRARYDIR - Preferred library directory e.g. /lib -\endverbatim - - - -\section python_start Getting Started - -To use the %OpenMesh Python Bindings we first need to import the openmesh module: - -\dontinclude python_tutorial.py -\skipline from - -The module provides two mesh classes: One for polygonal meshes (PolyMesh) and -one for triangle meshes (TriMesh). You should use triangle meshes whenever -possible, since they are usually more efficient. In addition, some algorithms -are only implemented for triangle meshes while triangle meshes inherit the full -functionality of polygonal meshes. - -The following code creates a new triangle mesh: - -\skipline mesh - - - -\section python_add Adding Items to a Mesh - -We can add a new vertex to the mesh by calling the add_vertex() member function. -This function gets a coordinate and returns a handle to the newly inserted -vertex. - -\skipline vh0 -\until vh4 - -To add a new face to the mesh we have to call add_face(). This function gets the -handles of the vertices that make up the new face and returns a handle to the -newly inserted face: - -\skipline fh0 -\until fh2 - -We can also use a Python list to add a face to the mesh: - -\skipline vh_list -\until fh3 - - - -\section python_iterators Iterators and Circulators - -Now that we have added a couple of vertices to the mesh, we can iterate over -them and print out their indices: - -\skipline for -\until vh.idx() - -We can also iterate over halfedges, edges and faces by calling mesh.halfedges(), -mesh.edges() and mesh.faces() respectively: - -\skipline iterate -\until fh.idx() - -To iterate over the items adjacent to another item we can use one of the -circulator functions. For example, to iterate over the vertices adjacent to -another vertex we can call mesh.vv() and pass the handle of the center vertex: - -\skipline for -\until vh.idx() - -We can also iterate over the adjacent halfedges, edges and faces: - -\skipline iterate -\until fh.idx() - -To iterate over the items adjacent to a face we can use the following functions: - -\skipline iterate -\until fh.idx() - - - -\section python_props Properties - -%OpenMesh allows us to dynamically add custom properties to a mesh. We can add -properties to vertices, halfedges, edges, faces and the mesh itself. To -add a property to a mesh (and later access its value) we have to use a property -handle of the appropriate type: - -\li VPropHandle (for vertex properties) -\li HPropHandle (for halfedge properties) -\li EPropHandle (for edge properties) -\li FPropHandle (for face properties) -\li MPropHandle (for mesh properties) - -The following code shows how to add a vertex property to a mesh: - -\skipline prop_handle -\until mesh - -The second parameter of the function add_property() is optional. The parameter -is used to specify a name for the new property. This name can later be used -to retrieve a handle to the property using the get_property_handle() member -function. - -Now that we have added a vertex property to the mesh we can set and get its -value. Here we will use the property to store the center of gravity of each -vertex' neighborhood: - -\skipline for -\until mesh.set_property - -Properties use Python's type system. This means that we can use the same -property to store values of different types (e.g. store both strings and -integers using the same vertex property). Properties are initialized to the -Python built-in constant None. - -To remove a property we have to call remove_property() with the appropriate -property handle: - -\skipline mesh.remove_property - - - -\section python_propman Property Managers - -Another way to add and remove a property is to use a property manager. A -Property manager encapsulates a property and manages its lifecycle. A Property -manager also provides a number of convenience functions to access the enclosed -property. - -There are four different types of property managers. One for each type of mesh -item: - -\li VPropertyManager (for vertex properties) -\li HPropertyManager (for halfedge properties) -\li EPropertyManager (for edge properties) -\li FPropertyManager (for face properties) - -Property managers automatically add a new property to a mesh when they are -initialized. Thus the following code not only creates a new vertex property -manager, but also adds a new vertex property to the mesh: - -\skipline prop_man - -Property managers allow us to conveniently set the property value for an entire -range of mesh items: - -\skipline prop_man - -They also allow us to use the subscript operator to set and get property values. -Here we will once again use a property to store the center of gravity of each -vertex' neighborhood: - -\skipline for -\until prop_man[vh] /= valence - -Properties that are encapsulated by a property manager are automatically removed -from the mesh when the property manager goes out of scope (i.e. the property -manager is garbage collected). - - - -\section python_io Read and write meshes from files - -You can read and write meshes from files using the read_mesh() and write_mesh() -functions: - -\skipline mesh -\until write_mesh(mesh, "bunny.obj") - -The file type is automatically deduced from the file extension. %OpenMesh -currently supports four file types: .off, .obj, .stl and .om - -The behaviour of the I/O functions can be controlled by passing an instance of -the Options class to either read_mesh() or write_mesh(). The class controls the -behaviour of the I/O functions by means of enabled/disabled bits in a bitset: - -\skipline mesh -\until print "something went wrong" - -Other available option bits include: - --# mode bits - control binary reading/writing - - Options.Binary - - Options.MSB - - Options.LSB - - Options.Swap (MSB|LSB) --# property bits - controls which standard properties to read/write - - Options.VertexNormal - - Options.VertexTexCoord - - Options.VertexColor - - Options.FaceNormal - - Options.FaceColor - - Options.ColorAlpha - - Options.ColorFloat - -\note You have to pass an instance of the Options class to the I/O functions, -i.e. you cannot directly pass one of the option bits. For example, directly -passing Options.Binary to either one of the functions will cause an error. - -When reading a file the options are used as hints, i.e. depending on the format -we can help the reader to interpret the data correctly. - -\note If you want to read a property from a file the property must have been -requested prior to reading the file. - -When writing the mesh the mode bits control whether to use the binary variant of -the respective file format and the desired byte-ordering. - - - -\section python_examples Additional Code Examples - -You can use our unit tests to learn more about the %OpenMesh Python Bindings. -They are located in the src/Python/Unittests subdirectory. - - - -\section python_cpp Python and C++ - -The interface of the Python Bindings is to a large extent identical to the -interface of the original C++ implementation of %OpenMesh. You should therefore -be able to use the C++ documentation as a reference for the Python Bindings. In -particular, the classes KernelT, PolyMeshT and TriMeshT provide a good overview -of the available mesh member functions. That being said, there are a number of -small differences. For example, whenever the C++ implementation returns a -reference to an object that is managed by %OpenMesh, the Python Bindings will -return a copy of that object. This is due to the fact that Python does not have -a language feature that is analogous to C++ references. One example of such a -function is the point() member function of the PolyMesh and TriMesh classes. -Unlike its C++ counterpart, the function does not return a reference to the -requested point. It instead returns a copy of the point. This implies that you -have to use the set_point() member function to change the value of a point. The -same applies to the following functions: normal(), color(), property(), -status(), etc. - - - -
    The complete source looks like this: - -\include python_tutorial.py - - -**/ diff --git a/Doc/tools.docu b/Doc/tools.docu index 5da44bcd..7ae8c68a 100644 --- a/Doc/tools.docu +++ b/Doc/tools.docu @@ -6,6 +6,7 @@ \li \subpage subdivider_docu \li \subpage vdpm_docu \li \subpage smoother_docu +\li \subpage smarttagger_docu \li Miscellaneous OpenMesh::StripifierT diff --git a/Doc/tutorial_03.docu b/Doc/tutorial_03.docu index 7d8fb228..d8e43d33 100644 --- a/Doc/tutorial_03.docu +++ b/Doc/tutorial_03.docu @@ -1,7 +1,7 @@ /** \page tutorial_03 Using (custom) properties This examples shows: -- How to add and remove custom properties, +- How to add and remove custom properties - How to get and set the value of a custom property In the last example we computed the barycenter of each vertex' @@ -11,44 +11,98 @@ let %OpenMesh manage the data. It would be even more helpful if we could attach such properties dynamically to the mesh. -%OpenMesh provides dynamic properties, which can be attached to each -mesh entity (vertex, face, edge, halfedge, and the mesh itself). We -distinguish between custom and standard properties. A custom property -is any user-defined property and is accessed via the member function -\c property(..) via a handle and an entity handle -(e.g. VertexHandle). Whereas the standard properties are accessed via -special member functions, e.g. the vertex position is accessed with \c -point(..) and a vertex handle. +Custom properties can be conveniently created and attached to meshes by creating an object of type OpenMesh::PropertyManager. A PropertyManager manages the lifetime of the property and provides read / write access to its values. -In this example we will store the \c cog-value (see previous example) -in an additional vertex property instead of keeping it in a separate -array. To do so we define first a so-called property handle with the desired -type (\c MyMesh::Point) and register the handle at the mesh: +You can use the typedefs VProp, HProp, EProp, FProp, and MProp in order to create a PropertyManager attached to vertices, halfedge, edges, faces and the mesh respectively. Each of these takes as template argument the type of the property value that is attached to each element (e.g., \p int, \p double, etc.). + +We differentiate between two kinds of properties. Named and temporary properties. Temporary properties are created by just providing the constructor with a mesh on which the property should be created. These properties will be removed as soon as the PropertyManager goes out of scope. If in addition to the mesh a property name is provided, a named property will be created which will stay alive even after the PropertyManager goes out of scope. If a PropertyManager is given a name of an already existing property, it will provide read and write access to the same property. + +Finally, an optional first parameter can be given containing a value that will be used to initialize the property for all elements if the property is freshly created (i.e. always for temporary properties, and only the first time a specific name is used). + + +Here are a few examples of how to create and access mesh properties: + +\code +// Add a temporary mesh property that stores a double value for every vertex +auto temperature = OpenMesh::VProp(mesh); +OpenMesh::VertexHandle vh = ...; +temperature[vh] = 1.0; +// The temperature property will be removed from the mesh when the handle reaches the end of the scope. + +// Obtain an existing property that stores a 2D vector for every halfedge +// (or create that property if it does not exist already) and initilize it with the Vector(1,1)) +auto uv = OpenMesh::HProp(mesh, "uv", OpenMesh::Vec2d(1,1)); +OpenMesh::VertexHandle heh = ...; +std::cout << temperature[heh][0] << " " << temperature[heh][1] << std::endl; + +// Obtain an existing mesh property (or create that property if it does not exist already) +// containing a description string +auto desc = OpenMesh::MProp(mesh, "desc"); +*desc = "This is a very nice mesh."; +\endcode + +--- + +## Code Example + +In this example, we will store the \c cog value (see previous example) in a vertex property instead of keeping it in a separate array. +To do so, we first add a (temporary) property of the desired element type (OpenMesh::VertexHandle) and value type (\c %MyMesh::Point) to the mesh: \dontinclude 03-properties/smooth.cc -\skipline vertex property stores -\until mesh.add +\skipline VProp -
    The \c mesh allocates enough memory to hold as many elements of type -\c MyMesh::Point as number of vertices exist, and of course the mesh -synchronizes all insert and delete operations on the vertices with the -vertex properties. +Enough memory is allocated to hold as many values of \c %MyMesh::Point as there are vertices. +All insert and delete operations on the mesh are synchronized with the attached properties. -Once the wanted property is registered we can use the property to -calculate the barycenter of the neighborhood of each vertex \c v_it +Once the property is created, we can use it to compute the centers of the neighborhood of each vertex: -\dontinclude 03-properties/smooth.cc -\skipline vv_it= +\skipline mesh.vertices +\until cog[vh] /= valence \until } -\until mesh.prop -
    and finally set the new position for each vertex \c v_it +Finally, we set the new position for each vertex: -\dontinclude 03-properties/smooth.cc -\skipline mesh.set_point +\skipline mesh.vertices +\until mesh.point +\until } -
    Below is the complete source code: +Below is the complete source code: \include 03-properties/smooth.cc -*/ \ No newline at end of file +--- + +## Property Lifetime + +In the above example, we chose to use VProp without a name. This causes the created property to automatically be removed from the mesh as soon as we leave the scope of the associated handle variable \c cog. + +If, instead, a property is desired to survive its local scope, it should be created with a name. For example: + +\code + auto face_area = OpenMesh::FProp(mesh, "face_area"); +\endcode + +At a later time, we can access the same property by using the same name. If we want to make sure, that we access a property that has already been created earlier, we can use hasProperty() to test whether a mesh has the desired property: +\code + if (OpenMesh::hasProperty(mesh, "face_area")) { + // Property exists. Do something with it. + auto valley = OpenMesh::FProp(mesh, "face_area"); + } + else { + // Property does not exist. Do something else. + } +\endcode + +--- + +## Low-Level Property API + +The property managers VProp, HProp, EProp, FProp and MProp are the convenient high-level interface for creating and accessing mesh properties. + +Beneath these convenience functions, there is also a low-level property interface where handle and property lifetime must be managed manually. This interface is accessed through a mesh's add_property(), get_property(), remove_property(), and property() functions and several property handle classes (OpenMesh::VPropHandleT, OpenMesh::HPropHandleT, OpenMesh::EPropHandleT, OpenMesh::FPropHandleT, OpenMesh::MPropHandleT). + +--- + + + +*/ diff --git a/Doc/tutorial_08.docu b/Doc/tutorial_08.docu index 394e81d5..2a221644 100644 --- a/Doc/tutorial_08.docu +++ b/Doc/tutorial_08.docu @@ -55,7 +55,7 @@ ASCII is not a real option and will be selected, if binary was not defined. Format/OptionASCIIBinaryMSBLSBSwapVertexNormalVertexColorVertexTexCoordEdgeColorFaceNormalFaceColorFaceTexCoordColorAlphaColorFloatCustom OBJx xx *)x xxx OFFxx x xxx x xx -PLYxxxx xxx xxx **) +PLYxxxx xxx x xxx **) OM xxxxxxxxxx (\ref tutorial_09 ) STLxxxx VTK ***)x diff --git a/Doc/tutorial_09.docu b/Doc/tutorial_09.docu index 5f83123a..1b2d4f09 100644 --- a/Doc/tutorial_09.docu +++ b/Doc/tutorial_09.docu @@ -1,186 +1,84 @@ -/** \page tutorial_09 Storing custom properties +/** \page tutorial_09 Using custom properties (old style) -The %OpenMesh' proprietary OM format allows to store and restore -custom properties along with the standard properties. For it we have -to use named custom properties like the following one +This small code example shows how to attach and access additional properties on a mesh. -\dontinclude 09-persistence/persistence.cc -\skipline VPropHandleT -\skipline mesh.add_property +Note that this is an old style of using properties. Nowadays you should use the OpenMesh::PropertyManager instead. -Here we registered a float property for the vertices at the mesh with -name "vprop_float". The name of a property, that we want to make -persistent, must follow a few rules +When you want to add an additional properties you have to attach it to a primitive of the +mesh. You can attach to verticies, halfedges, edges, faces or to the mesh itself. Use the +add_property function: --# max. 256 characters long --# The prefixes \c "v:", \c "h:", \c "e:", \c "f:" and \c "m:" are reserved. +\code -If we stick to this rules we are fine. Furthermore we have to -consider, that the names are handled case-sensitive. + // for each vertex an extra double value + OpenMesh::VPropHandleT< double > vprop_double; + mesh.add_property( vprop_double ,"Vertex property name"); -To actually make a custom property persistent we have to set the -persistent flag in the property with + // for each halfedge an extra int value + OpenMesh::HEPropHandleT< int > heprop_int; + mesh.add_property( heprop_int ,"Halfedge property name"); -\skipline mesh.property(vprop_float).set_persistent + // for each edge an extra float value + OpenMesh::EPropHandleT< float > eprop_float; + mesh.add_property( eprop_float ,"Edge property name"); -Now we can use \c IO::mesh_write() to write the mesh to a file on -disk. The custom properties are added after the standard properties -in the file, with the name and it's binary size. These two pieces of -information are evaluated when reading the file again. To successfully -restore the custom properties, the mesh must have registered named -properties with equal names (case-sensitive compare). Additionally, -when reading the data, the number of bytes read for a property must -match the provided number in the file. If the OM reader did not find a -suitable named property, it will simply skip it. If the number of bytes -do not match, the complete restore will be terminated and \c -IO::read_mesh() will return \c false. And if the data cannot be -restored, because the appropriate restore method is not available the -exception std::logic_error() will be thrown. + // for each face an extra double value + OpenMesh::FPropHandleT< double > fprop_double; + mesh.add_property( fprop_double ,"Face property name"); -Since we now know the behaviour, we need to know what kind of data can -we store? Without any further effort, simply using named properties -and setting the persistent flag, we can store following types + // for the mesh an extra string + OpenMesh::MPropHandleT< string > mprop_string; + mesh.add_property( mprop_string , "Mesh property name "); -- bool, stored as a bitset -- all other fundamental types except long double, (unsigned) long and size_t -- std::string, each up to 65536 characters long -- OpenMesh::Vec[1,2,3,4,6][c,uc,s,us,i,ui,f,d] +\endcode -For further reading we call these types basic types. Apparently we -cannot store non-basic types, which are +Accessing to the property is available via the property function. +This function gets the property handle (created above) and a +handle (e.g. to a vertex or a face): -- pointers -- structs/classes -- even more complex data structures, like container of containers. +\code + // Write something to a face property: + mesh->property( , ) = ; -However there is a way to store custom types ( else we could not store -std::string). Let's start with an more simple custom data. For -instance we have a struct \c MyData like this + // E.g. + for (f_it=mesh->faces_begin(); f_it!=mesh->faces_end() ; ++f_it) { + mesh->property( fprop_double , *f_it ) = 0.0; + } +\endcode -\dontinclude 09-persistence/persistence.cc -\skipline struct MyData -\until vec4fval -\skipline }; +As you can attach properties to the mesh, you might want to add a property in one +function and access it in another, where the handle is not yet available. You can +retrieve the required handle in the following way (Note that the handles are accessed by their name and type): -Here we keep an int, bool, double value and a vector of 4 floats, which -are all basic types. Then we need to specialize the template struct -OpenMesh::IO::binary<> within the namespace \c OpenMesh::IO +\code + // Specify handle type (Double face handle in this case): + OpenMesh::FPropHandleT< double > fprop_double; -\skipline binary + // Try to get handle with the given name. + if ( !mesh_.get_property_handle(fprop_double,"Face property name") ) { + std::cerr << "Unable to retrieve property! " << std::endl; + return + } -Remember not to use long double, (unsigned) long and size_t as basic types -because of inconsistencies between 32/64bit architectures. + // If we reach this point, we have a valid handle. +\endcode -Herein we have to implement the following set of static member -variables and functions: +The properties can be removed by calling remove_property: -\skipline is_streamable -\skipline size_of -\skipline size_of -\skipline store -\skipline restore +\code + // Remove the property + mesh->remove_property(fprop_double); +\endcode -The flag \c is_streamable has to be set to \c true. Else the data -cannot be stored at all. -
    \c size_of methods
    -Since the size of the custom data can be static, which means we know -the size at compile time, or the size of it is dynamic, which means me -the size is known at runtime, we have to provide the two \c size_of() -methods. +A useful function to see all properties on the mesh is: -The first declaration is for the static case, while the second for the -dynamic case. Though the static case is more simple, it is not -straight forward. We cannot simply use \c sizeof() to determine the -data size, because it will return the number ob bytes it needs in -memory (possible 32bit alignment). Instead we need the binary size, -hence we have to add up the single elements in the struct. +\code + // Print all available properties + mesh->property_stats(); +\endcode -\dontinclude 09-persistence/persistence.cc -\skipline return sizeof +A useful class for handling properties and their lifetime is the OpenMesh::PropertyManager. -Actually we would need to sum up the single elements of the vector, -but in this case we know for sure the result (4 floats make 16 bytes, -which is 32bit aligned therefore \c sizeof() returns the wanted -size). But keep in mind, that this a potential location for errors, -when writing custom binary support. - -The second declaration is for the dynamic case, where the custom data -contains pointers or references. This static member must properly -count the data, by disolving the pointers/references, if this data has -to be stored as well. In the dynamic stetting the static variant cannot return -the size, therefore it must return \c IO::UnknownSize. - -In this case the dynamic variant simply returns the size by calling the static -variant, as the sizes are identical for both cases. - -
    \c store / \c restore
    - -For the dynamic case as for the static case, we have to make up a -scheme how we would store the data. One option is to store the length -of the data and then store the data itself. For instance the type \c -std::string is implemented this way. (We store first the length in a -16bit word (=> max. length 65536), then the characters follow. Hence -\c size_of() returns 2 bytes for the length plus the actual length of -the value \c v.) Since \c MyData contains only basic types we can -implement the necessary methods \c store and \c restore, by simply -breaking up the data into the basic types using the pre-defined -store/restore methods for them: - -\skipline static size_t store -\until } -\skipline static size_t restore -\until } - -It's very important, that the store/restore methods count the -written/read bytes correctly and return the value. On error both -functions must return 0. - -A more complex situation is given with the following property - -\dontinclude 09-persistence/persistence.cc -\skipline MyMap -\skipline mprop_map - -In this case the data contains a container, a map from strings to -integer numbers. If we want to store this as well, we need to make up -a scheme how the map will be stored in a sequential layout. First we -store the number of elements in the map. Then, since the map has an -iterator, we simply iterate over all elements and store each pair -(key/value). This procedure is equal for the \c size_of(), \c store(), and \c -restore() methods. For example the \c size_of() methods look like this - -\dontinclude 09-persistence/persistence.cc -\skip binary< MyMap > -\skipline static size_t size_of -\skipline static size_t size_of -\until } -\until } - -The implementation of \c store() and \c restore() follow a similar pattern. - -The given example program does the following steps - --# Create a mesh and generate a cube --# Add a few custom properties --# Fill them with test data --# Make the properties persistent --# Store mesh in a file named 'persistent-check.om' --# Clear the mesh --# Restore mesh --# Check the content on equality with the test data. - -Since the example is a little bit longer than usual the source is in -several files. The main program is in \c persistence.cc, the cube -generator in \c generate_cube.hh, \c stats.hh provides little tools to -display information about the mesh and the properties, the file \c -fill_props.hh providing the test data, and \c int2roman.hh/.cc, which -is used in fill_props.hh. All necessary parts are in \c -persistence.cc, which is displayed in full length below. For the other -files please have a look in the directory \c -OpenMesh/Doc/Tutorial/09-persistence/. - -\include 09-persistence/persistence.cc - -*/ \ No newline at end of file +*/ diff --git a/Doc/tutorial_10.docu b/Doc/tutorial_10.docu new file mode 100644 index 00000000..81ff26f2 --- /dev/null +++ b/Doc/tutorial_10.docu @@ -0,0 +1,186 @@ +/** \page tutorial_10 Storing custom properties + +The %OpenMesh' proprietary OM format allows to store and restore +custom properties along with the standard properties. For it we have +to use named custom properties like the following one + +\dontinclude 10-persistence/persistence.cc +\skipline VPropHandleT +\skipline mesh.add_property + +Here we registered a float property for the vertices at the mesh with +name "vprop_float". The name of a property, that we want to make +persistent, must follow a few rules + +-# max. 256 characters long +-# The prefixes \c "v:", \c "h:", \c "e:", \c "f:" and \c "m:" are reserved. + +If we stick to this rules we are fine. Furthermore we have to +consider, that the names are handled case-sensitive. + +To actually make a custom property persistent we have to set the +persistent flag in the property with + +\skipline mesh.property(vprop_float).set_persistent + +Now we can use \c IO::mesh_write() to write the mesh to a file on +disk. The custom properties are added after the standard properties +in the file, with the name and it's binary size. These two pieces of +information are evaluated when reading the file again. To successfully +restore the custom properties, the mesh must have registered named +properties with equal names (case-sensitive compare). Additionally, +when reading the data, the number of bytes read for a property must +match the provided number in the file. If the OM reader did not find a +suitable named property, it will simply skip it. If the number of bytes +do not match, the complete restore will be terminated and \c +IO::read_mesh() will return \c false. And if the data cannot be +restored, because the appropriate restore method is not available the +exception std::logic_error() will be thrown. + +Since we now know the behaviour, we need to know what kind of data can +we store? Without any further effort, simply using named properties +and setting the persistent flag, we can store following types + +- bool, stored as a bitset +- all other fundamental types except long double, (unsigned) long and size_t +- std::string, each up to 65536 characters long +- OpenMesh::Vec[1,2,3,4,6][c,uc,s,us,i,ui,f,d] + +For further reading we call these types basic types. Apparently we +cannot store non-basic types, which are + +- pointers +- structs/classes +- even more complex data structures, like container of containers. + +However there is a way to store custom types ( else we could not store +std::string). Let's start with an more simple custom data. For +instance we have a struct \c MyData like this + +\dontinclude 10-persistence/persistence.cc +\skipline struct MyData +\until vec4fval +\skipline }; + +Here we keep an int, bool, double value and a vector of 4 floats, which +are all basic types. Then we need to specialize the template struct +OpenMesh::IO::binary<> within the namespace \c OpenMesh::IO + +\skipline binary + +Remember not to use long double, (unsigned) long and size_t as basic types +because of inconsistencies between 32/64bit architectures. + +Herein we have to implement the following set of static member +variables and functions: + +\skipline is_streamable +\skipline size_of +\skipline size_of +\skipline store +\skipline restore + +The flag \c is_streamable has to be set to \c true. Else the data +cannot be stored at all. + +
    \c size_of methods
    + +Since the size of the custom data can be static, which means we know +the size at compile time, or the size of it is dynamic, which means me +the size is known at runtime, we have to provide the two \c size_of() +methods. + +The first declaration is for the static case, while the second for the +dynamic case. Though the static case is more simple, it is not +straight forward. We cannot simply use \c sizeof() to determine the +data size, because it will return the number ob bytes it needs in +memory (possible 32bit alignment). Instead we need the binary size, +hence we have to add up the single elements in the struct. + +\dontinclude 10-persistence/persistence.cc +\skipline return sizeof + +Actually we would need to sum up the single elements of the vector, +but in this case we know for sure the result (4 floats make 16 bytes, +which is 32bit aligned therefore \c sizeof() returns the wanted +size). But keep in mind, that this a potential location for errors, +when writing custom binary support. + +The second declaration is for the dynamic case, where the custom data +contains pointers or references. This static member must properly +count the data, by disolving the pointers/references, if this data has +to be stored as well. In the dynamic stetting the static variant cannot return +the size, therefore it must return \c IO::UnknownSize. + +In this case the dynamic variant simply returns the size by calling the static +variant, as the sizes are identical for both cases. + +
    \c store / \c restore
    + +For the dynamic case as for the static case, we have to make up a +scheme how we would store the data. One option is to store the length +of the data and then store the data itself. For instance the type \c +std::string is implemented this way. (We store first the length in a +16bit word (=> max. length 65536), then the characters follow. Hence +\c size_of() returns 2 bytes for the length plus the actual length of +the value \c v.) Since \c MyData contains only basic types we can +implement the necessary methods \c store and \c restore, by simply +breaking up the data into the basic types using the pre-defined +store/restore methods for them: + +\skipline static size_t store +\until } +\skipline static size_t restore +\until } + +It's very important, that the store/restore methods count the +written/read bytes correctly and return the value. On error both +functions must return 0. + +A more complex situation is given with the following property + +\dontinclude 10-persistence/persistence.cc +\skipline MyMap +\skipline mprop_map + +In this case the data contains a container, a map from strings to +integer numbers. If we want to store this as well, we need to make up +a scheme how the map will be stored in a sequential layout. First we +store the number of elements in the map. Then, since the map has an +iterator, we simply iterate over all elements and store each pair +(key/value). This procedure is equal for the \c size_of(), \c store(), and \c +restore() methods. For example the \c size_of() methods look like this + +\dontinclude 10-persistence/persistence.cc +\skip binary< MyMap > +\skipline static size_t size_of +\skipline static size_t size_of +\until } +\until } + +The implementation of \c store() and \c restore() follow a similar pattern. + +The given example program does the following steps + +-# Create a mesh and generate a cube +-# Add a few custom properties +-# Fill them with test data +-# Make the properties persistent +-# Store mesh in a file named 'persistent-check.om' +-# Clear the mesh +-# Restore mesh +-# Check the content on equality with the test data. + +Since the example is a little bit longer than usual the source is in +several files. The main program is in \c persistence.cc, the cube +generator in \c generate_cube.hh, \c stats.hh provides little tools to +display information about the mesh and the properties, the file \c +fill_props.hh providing the test data, and \c int2roman.hh/.cc, which +is used in fill_props.hh. All necessary parts are in \c +persistence.cc, which is displayed in full length below. For the other +files please have a look in the directory \c +OpenMesh/Doc/Tutorial/10-persistence/. + +\include 10-persistence/persistence.cc + +*/ diff --git a/Doc/tutorial_11.docu b/Doc/tutorial_11.docu new file mode 100644 index 00000000..f99724cf --- /dev/null +++ b/Doc/tutorial_11.docu @@ -0,0 +1,85 @@ +/** \page tutorial_11 Using Smart Handles + +This examples shows: +- How to use Smart Handles and ranges to navigate on the mesh +- How to use Smart Ranges + +So far we have used methods such as halfedge_handle(), next_halfedge_handle(), prev_halfedge_handle(), oppopsite_halfedge_handle(), face_handle(), to_vertex_handle(), and some others, to navigate on that mesh. These functions are defined on a mesh and require as input a handle to an element of the mesh, such as VertexHandle or HalfedgeHandle. In the following example we iterate over all vertices of a triangle mesh and for each vertex we create a list of the vertices that lie opposite of the edges in the ring around the vertex: + +\code +// iterate over vertices of the mesh +for (auto vh : mesh.vertices()) +{ + std::vector opposite_vertices; + // iterate over all outgoing halfedges + for (auto heh : mesh.voh_range(vh)) + { + // navigate to the opposite vertex and store it in the vector + opposite_vertices.push_back(mesh.to_vertex_handle(mesh.next_halfedge_handle(mesh.opposite_halfedge_handle(mesh.next_halfedge_handle(heh))))); + } +} +\endcode + +For a more concise way of navigating OpenMesh provides smart handles, OpenMesh::SmartVertexHandle, OpenMesh::SmartHalfedgeHandle, OpenMesh::SmartEdgeHandle, and OpenMesh::SmartFaceHandle. Smart handles are smart, because they know to which mesh they belong. This allows them to provide functions for navigating the mesh allowing us to write the above code much simpler: + +\code +// iterate over vertices of the mesh +for (auto vh : mesh.vertices()) +{ + // iterate over all outgoing halfedges + std::vector opposite_vertices; + for (auto heh : vh.outgoing_halfedges()) + { + // navigate to the opposite vertex and store it in the vector + opposite_vertices.push_back(heh.next().opp().next().to()); + } +} +\endcode + +The ranges of OpenMesh that are returned by functions like voh_range() or outgoing_halfedges() all provide a few methods than can simplify some calculations (see OpenMesh::SmartRangeT). One example is the to_vector() method which convertes the range of elements into a vector containing the elements. All of these methods take a functor as argument (sometimes optional) which is called for each element of the range. With this, the above code can also be implemented like this: + +\code +// iterate over vertices of the mesh +for (auto vh : mesh.vertices()) +{ + // create lambda that returns opposite vertex + auto opposite_vertex = [](OpenMesh::SmartHalfedgeHandle heh) { return heh.next().opp().next().to(); }; + // create vector containing all opposite vertices + auto opposite_vertices = vh.outgoing_halfedges().to_vector(opposite_vertex); +} +\endcode + +--- + +## Code Example + +In this example, we will use bi-laplacian smoothing on a mesh. We store the \c laplace vector which is the vector pointing from a vertex to the center of gravity of its neighboring vertices in a vertex property. + +\dontinclude 11-smart_handles/smooth.cc +\skipline laplace +\skipline laplace + +To compute the center of gravity, i.e. the average position, we use the avg() method of the range of 1-ring vertices and pass in a PropertyManager acting as functor returning the corresponding point of a vertex. + +\skipline points +\until avg(points) + +Similarily we compute the update vector as the laplace of the freshly computed laplace vectors by simply exchanging the points property manager with the laplace property manager. + +\skipline Iterate +\until bi_laplace + +Finally, we apply the update after damping it by a factor of -0.5. + +\skipline udpate points +\until bi_laplace + +Below is the complete source code: + +\include 11-smart_handles/smooth.cc + +--- + + + +*/ diff --git a/Doc/tutorial_main.docu b/Doc/tutorial_main.docu index d07e9ab7..908099dc 100644 --- a/Doc/tutorial_main.docu +++ b/Doc/tutorial_main.docu @@ -33,12 +33,14 @@ repeatedly replacing each vertex' position by the center of gravity
  • \subpage tutorial_02
  • \subpage tutorial_03
  • \subpage tutorial_04 +
  • \subpage tutorial_11
  • \subpage tutorial_05
  • \subpage tutorial_06
  • \subpage tutorial_07
  • \subpage tutorial_07b
  • \subpage tutorial_08
  • \subpage tutorial_09 +
  • \subpage tutorial_10 */ diff --git a/OpenMesh.pro b/OpenMesh.pro deleted file mode 100644 index f5e14c46..00000000 --- a/OpenMesh.pro +++ /dev/null @@ -1,18 +0,0 @@ -contains( OPENFLIPPER , OpenFlipper ){ - include( $$TOPDIR/qmake/all.include ) -} else { - include( $$TOPDIR/OpenMesh/qmake/all.include ) -} - -Subdirs() - -addSubdirs( src/OpenMesh/Core ) -addSubdirs( src/OpenMesh/Tools , src/OpenMesh/Core ) -addSubdirs( src/OpenMesh/Apps/commandlineDecimater , src/OpenMesh/Core src/OpenMesh/Tools) -addSubdirs( src/OpenMesh/Apps/Decimating/DecimaterGui , src/OpenMesh/Core src/OpenMesh/Tools) -addSubdirs( src/OpenMesh/Apps/mconvert , src/OpenMesh/Core src/OpenMesh/Tools) -addSubdirs( src/OpenMesh/Apps/QtViewer , src/OpenMesh/Core src/OpenMesh/Tools) -addSubdirs( src/OpenMesh/Apps/Smoothing , src/OpenMesh/Core src/OpenMesh/Tools) -addSubdirs( src/OpenMesh/Apps/Subdivider/commandlineSubdivider , src/OpenMesh/Core src/OpenMesh/Tools) -addSubdirs( src/OpenMesh/Apps/Subdivider/commandlineAdaptiveSubdivider , src/OpenMesh/Core src/OpenMesh/Tools) -addSubdirs( src/OpenMesh/Apps/Subdivider/SubdividerGui , src/OpenMesh/Core src/OpenMesh/Tools) diff --git a/README.md b/README.md index d8a82b67..d7703660 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ -# OpenMesh, 7.0 +# OpenMesh, 8.1 + +[![](https://www.graphics.rwth-aachen.de:9000/OpenMesh/OpenMesh/badges/master/pipeline.svg)](https://www.graphics.rwth-aachen.de:9000/OpenMesh/OpenMesh/commits/master) ## Getting OpenMesh @@ -10,6 +12,33 @@ https://www.graphics.rwth-aachen.de:9000/OpenMesh/OpenMesh.git The gitlab site can be found here: https://www.graphics.rwth-aachen.de:9000/OpenMesh/OpenMesh +The python bindings can be found here: +https://www.graphics.rwth-aachen.de:9000/OpenMesh/openmesh-python + +## Download Binaries + +The following binaries are created from the latest master. They are automatically tested and deployed. + +### Windows + +| Visual Studio Version: | 2017 | 2015 | +| -------- | -------- |-------- | +| 64-Bit shared, with apps | [Download](https://www.graphics.rwth-aachen.de:9000/OpenMesh/OpenMesh/-/jobs/artifacts/master/browse/build-release?job=VS2017-64-bit-shared-apps) | [Download](https://www.graphics.rwth-aachen.de:9000/OpenMesh/OpenMesh/-/jobs/artifacts/master/browse/build-release?job=VS2015-64-bit-shared-apps) | +| 32-Bit shared, with apps | - | [Download](https://www.graphics.rwth-aachen.de:9000/OpenMesh/OpenMesh/-/jobs/artifacts/master/browse/build-release?job=VS2015-32-bit-shared-apps) | +| 64-Bit static, with apps | [Download ](https://www.graphics.rwth-aachen.de:9000/OpenMesh/OpenMesh/-/jobs/artifacts/master/browse/build-release?job=VS2017-64-bit-static-apps) | [Download ](https://www.graphics.rwth-aachen.de:9000/OpenMesh/OpenMesh/-/jobs/artifacts/master/browse/build-release?job=VS2015-64-bit-static-apps) | +| 32-Bit static, with apps | - | [ Download ](https://www.graphics.rwth-aachen.de:9000/OpenMesh/OpenMesh/-/jobs/artifacts/master/browse/build-release?job=VS2015-32-bit-static-apps) | +| 64-Bit shared, no apps | [Download](https://www.graphics.rwth-aachen.de:9000/OpenMesh/OpenMesh/-/jobs/artifacts/master/browse/build-release?job=VS2017-64-bit-shared-no-apps) | [Download](https://www.graphics.rwth-aachen.de:9000/OpenMesh/OpenMesh/-/jobs/artifacts/master/browse/build-release?job=VS2015-64-bit-shared-no-apps) | +| 32-Bit shared, no apps | [Download](https://www.graphics.rwth-aachen.de:9000/OpenMesh/OpenMesh/-/jobs/artifacts/master/browse/build-release?job=VS2017-32-bit-shared-no-apps) | [Download](https://www.graphics.rwth-aachen.de:9000/OpenMesh/OpenMesh/-/jobs/artifacts/master/browse/build-release?job=VS2015-32-bit-shared-no-apps) | +| 64-Bit static, no apps | [Download ](https://www.graphics.rwth-aachen.de:9000/OpenMesh/OpenMesh/-/jobs/artifacts/master/browse/build-release?job=VS2017-64-bit-static-no-apps) | [Download ](https://www.graphics.rwth-aachen.de:9000/OpenMesh/OpenMesh/-/jobs/artifacts/master/browse/build-release?job=VS2015-64-bit-static-no-apps) | +| 32-Bit static, no apps | [ Download ](https://www.graphics.rwth-aachen.de:9000/OpenMesh/OpenMesh/-/jobs/artifacts/master/browse/build-release?job=VS2017-32-bit-static-no-apps) | [ Download ](https://www.graphics.rwth-aachen.de:9000/OpenMesh/OpenMesh/-/jobs/artifacts/master/browse/build-release?job=VS2015-32-bit-static-no-apps) | + +### Apple + [Download ](https://www.graphics.rwth-aachen.de:9000/OpenMesh/OpenMesh/-/jobs/artifacts/master/browse/build-release-cpp11?job=macos-cpp11) + +## Download Sources +[ Download Sources](https://www.graphics.rwth-aachen.de:9000/OpenMesh/OpenMesh/-/jobs/artifacts/master/browse/?job=Sources ) + + ## Installing Unpack the tar-ball to a suitable place. diff --git a/VERSION b/VERSION index 7028d24e..77582fff 100644 --- a/VERSION +++ b/VERSION @@ -1,5 +1,5 @@ -VERSION=7.0 -MAJOR=7 +VERSION=9.0 +MAJOR=9 MINOR=0 PATCH=0 ID=OPENMESH diff --git a/cmake/ACGCommon.cmake b/cmake/ACGCommon.cmake index c7220b82..65a38530 100644 --- a/cmake/ACGCommon.cmake +++ b/cmake/ACGCommon.cmake @@ -3,10 +3,10 @@ if (EXISTS ${CMAKE_SOURCE_DIR}/${CMAKE_PROJECT_NAME}.cmake) endif () # prevent build in source directory -if ("${CMAKE_BINARY_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}") - message (SEND_ERROR "Building in the source directory is not supported.") - message (FATAL_ERROR "Please remove the created \"CMakeCache.txt\" file, the \"CMakeFiles\" directory and create a build directory and call \"${CMAKE_COMMAND} \".") -endif ("${CMAKE_BINARY_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}") + if ("${CMAKE_BINARY_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}") + message (SEND_ERROR "Building in the source directory is not supported.") + message (FATAL_ERROR "Please remove the created \"CMakeCache.txt\" file, the \"CMakeFiles\" directory and create a build directory and call \"${CMAKE_COMMAND} \".") + endif ("${CMAKE_BINARY_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}") # allow only Debug and Release builds set (CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "") @@ -87,15 +87,6 @@ else () set (ACG_PROJECT_BINDIR "bin") endif () -if( NOT APPLE ) - # check 64 bit - if( CMAKE_SIZEOF_VOID_P MATCHES 4 ) - set( HAVE_64_BIT 0 ) - else( CMAKE_SIZEOF_VOID_P MATCHES 4 ) - set( HAVE_64_BIT 1 ) - endif( CMAKE_SIZEOF_VOID_P MATCHES 4 ) -endif ( NOT APPLE ) - # allow a project to modify the directories if (COMMAND acg_modify_project_dirs) acg_modify_project_dirs () @@ -115,24 +106,14 @@ macro (acg_set_target_props target) SKIP_BUILD_RPATH 0 ) elseif (APPLE AND NOT ACG_PROJECT_MACOS_BUNDLE) - if (NOT (CMAKE_MAJOR_VERSION LESS 3) ) - # save rpath - set_target_properties ( - ${target} PROPERTIES - INSTALL_RPATH "@executable_path/../${ACG_PROJECT_LIBDIR}" - MACOSX_RPATH 1 - #BUILD_WITH_INSTALL_RPATH 1 - SKIP_BUILD_RPATH 0 - ) - else() - # save rpath via install name dir - set_target_properties ( - ${target} PROPERTIES - INSTALL_NAME_DIR "@executable_path/../${ACG_PROJECT_LIBDIR}" - #BUILD_WITH_INSTALL_RPATH 1 - SKIP_BUILD_RPATH 0 - ) - endif(NOT (CMAKE_MAJOR_VERSION LESS 3)) + # save rpath + set_target_properties ( + ${target} PROPERTIES + INSTALL_RPATH "@executable_path/../${ACG_PROJECT_LIBDIR}" + MACOSX_RPATH 1 + #BUILD_WITH_INSTALL_RPATH 1 + SKIP_BUILD_RPATH 0 + ) elseif (NOT APPLE) set_target_properties ( @@ -152,155 +133,6 @@ include (ACGCompiler) # define INCLUDE_TEMPLATES for everything we build add_definitions (-DINCLUDE_TEMPLATES) -#unset cached qt variables which are set by all qt versions. version is the major number of the qt version (e.g. 4 or 5, not 4.8) -macro (acg_unset_qt_shared_variables version) - if (ACG_INTERNAL_QT_LAST_VERSION) - if (NOT ${ACG_INTERNAL_QT_LAST_VERSION} EQUAL ${version}) - unset(QT_BINARY_DIR) - unset(QT_PLUGINS_DIR) - unset(ACG_INTERNAL_QT_LAST_VERSION) - endif() - endif() - set (ACG_INTERNAL_QT_LAST_VERSION "${version}" CACHE INTERNAL "Qt Version, which was used on the last time") -endmacro() - -# look for selected qt dependencies -macro (acg_qt4) - if (NOT QT4_FOUND) - acg_unset_qt_shared_variables(4) - find_package (Qt4 COMPONENTS QtCore QtGui ${ARGN}) - - set (QT_USE_QTOPENGL 1) - set (QT_USE_QTNETWORK 1) - set (QT_USE_QTSCRIPT 1) - set (QT_USE_QTSQL 1) - set (QT_USE_QTXML 1) - set (QT_USE_QTXMLPATTERNS 1) - set (QT_USE_QTHELP 1) - set (QT_USE_QTWEBKIT 1) - set (QT_USE_QTUITOOLS 1) - - include (${QT_USE_FILE}) - endif () -endmacro () - -macro (acg_qt5) - - if(POLICY CMP0020) - # Automatically link Qt executables to qtmain target on Windows - cmake_policy(SET CMP0020 NEW) - endif(POLICY CMP0020) - #if (NOT QT5_FOUND) - - #set (QT_MIN_VERSION ${ARGN}) - - #try to find qt5 automatically - #for custom installation of qt5, dont use any of these variables - set (QT5_INSTALL_PATH "" CACHE PATH "Path to Qt5 directory which contains lib and include folder") - if (EXISTS "${QT5_INSTALL_PATH}") - set (CMAKE_PREFIX_PATH "${CMAKE_PREFIX_PATH};${QT5_INSTALL_PATH}") - set (QT5_INSTALL_PATH_EXISTS TRUE) - endif() - - - - find_package (Qt5Core QUIET) - - #find WINDOWS_SDK to avoid qt error. This must be done BEFORE Qt5Widgets is searched - if (Qt5Core_FOUND AND WIN32) - string(REGEX REPLACE "^([0-9]+)\\.[0-9]+\\.[0-9]+.*" "\\1" QT_VERSION_MAJOR "${Qt5Core_VERSION_STRING}") - string(REGEX REPLACE "^[0-9]+\\.([0-9])+\\.[0-9]+.*" "\\1" QT_VERSION_MINOR "${Qt5Core_VERSION_STRING}") - string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" QT_VERSION_PATCH "${Qt5Core_VERSION_STRING}") - - if ( (QT_VERSION_MAJOR EQUAL 5) AND (QT_VERSION_MINOR LESS 3 OR ( QT_VERSION_MINOR EQUAL 3 AND QT_VERSION_PATCH EQUAL 0 )) ) # for all Qt version > 5.0.0 and < 5.3.1 - #glu32.lib is needed by qt5 opengl version. it cannot find it by itself so we help qt - #this block has to be executed, before Qt5Gui is searched, otherwise we will end up with the (not so useful) QT5 error message - set(WINDOWS_SDK_LIBS "COULD_NOT_FOUND" CACHE PATH "Path to the latest windows sdk libs which includes glu32.lib. Used by Qt5.") - if (EXISTS "${WINDOWS_SDK_LIBS}\\glu32.lib") - set (CMAKE_PREFIX_PATH "${CMAKE_PREFIX_PATH};${WINDOWS_SDK_LIBS}") - elseif(QT5_INSTALL_PATH_EXISTS) #trying to install qt5. notify about missing sdk before the qt message comes - message(FATAL_ERROR "Could not find glu32.lib. This is necessary for QT5 OpenGL version for windows, spleace specify glu32.lib in WINDOWS_SDK_LIB or install Qt version >= 5.3.1") - endif() - endif() - endif(Qt5Core_FOUND AND WIN32) - - find_package (Qt5Gui QUIET) - find_package (Qt5OpenGL QUIET) - - - if (Qt5Core_FOUND AND Qt5Gui_FOUND AND Qt5OpenGL_FOUND) - set (QT5_FOUND TRUE) - endif() - - if (QT5_FOUND) - acg_unset_qt_shared_variables(5) - - #set plugin dir - list(GET Qt5Gui_PLUGINS 0 _plugin) - if (_plugin) - get_target_property(_plugin_full ${_plugin} LOCATION) - get_filename_component(_plugin_dir ${_plugin_full} PATH) - set (QT_PLUGINS_DIR "${_plugin_dir}/../" CACHE PATH "Path to the qt plugin directory") - elseif(QT5_INSTALL_PATH_EXISTS) - set (QT_PLUGINS_DIR "${QT5_INSTALL_PATH}/plugins/" CACHE PATH "Path to the qt plugin directory") - elseif() - set (QT_PLUGINS_DIR "QT_PLUGIN_DIR_NOT_FOUND" CACHE PATH "Path to the qt plugin directory") - endif(_plugin) - - #set binary dir for fixupbundle - if(QT5_INSTALL_PATH_EXISTS) - set(_QT_BINARY_DIR "${QT5_INSTALL_PATH}/bin") - else() - get_target_property(_QT_BINARY_DIR ${Qt5Widgets_UIC_EXECUTABLE} LOCATION) - get_filename_component(_QT_BINARY_DIR ${_QT_BINARY_DIR} PATH) - endif(QT5_INSTALL_PATH_EXISTS) - - set (QT_BINARY_DIR "${_QT_BINARY_DIR}" CACHE PATH "Qt5 binary Directory") - mark_as_advanced(QT_BINARY_DIR) - - set (CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) - - include_directories(${Qt5Core_INCLUDE_DIRS}) - include_directories(${Qt5Gui_INCLUDE_DIRS}) - include_directories(${Qt5OpenGL_INCLUDE_DIRS}) - add_definitions(${Qt5Core_DEFINITIONS}) - add_definitions(${Qt5Gui_DEFINITIONS}) - add_definitions(${Qt5OpenGL_DEFINITIONS}) - - if ( NOT MSVC ) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") - endif() - - set (QT_LIBRARIES ${Qt5Core_LIBRARIES} ${Qt5Widgets_LIBRARIES} - ${Qt5Gui_LIBRARIES} ${Qt5OpenGL_LIBRARIES}) - - if (MSVC) - set (QT_LIBRARIES ${QT_LIBRARIES} ${Qt5Core_QTMAIN_LIBRARIES}) - endif() - - #add_definitions(-DQT_NO_OPENGL) - - #adding QT_NO_DEBUG to all release modes. - # Note: for multi generators like msvc you cannot set this definition depending of - # the current build type, because it may change in the future inside the ide and not via cmake - if (MSVC_IDE) - set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /DQT_NO_DEBUG") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /DQT_NO_DEBUG") - - set(CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_RELEASE} /DQT_NO_DEBUG") - set(CMAKE_CXX_FLAGS_MINSITEREL "${CMAKE_C_FLAGS_RELEASE} /DQT_NO_DEBUG") - - set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELEASE} /DQT_NO_DEBUG") - set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELEASE} /DQT_NO_DEBUG") - else(MSVC_IDE) - if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug") - add_definitions(-DQT_NO_DEBUG) - endif() - endif(MSVC_IDE) - - endif () -endmacro () - # unsets the given variable macro (acg_unset var) set (${var} "" CACHE INTERNAL "") @@ -311,35 +143,6 @@ macro (acg_set var value) set (${var} ${value} CACHE INTERNAL "") endmacro () -# test for OpenMP -macro (acg_openmp) - if (NOT OPENMP_NOTFOUND) - find_package(OpenMP) - if (OPENMP_FOUND) - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") - set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") - add_definitions(-DUSE_OPENMP) - else () - set (OPENMP_NOTFOUND 1) - endif () - endif () -endmacro () - -# test for FTGL -macro (acg_ftgl) - find_package (Freetype) - - if (FREETYPE_FOUND) - find_package (FTGL) - - if (FTGL_FOUND) - add_definitions (-DUSE_FTGL) - include_directories (${FTGL_INCLUDE_DIR} ${FREETYPE_INCLUDE_DIR_freetype2}) - set (FTGL_LIBS ${FREETYPE_LIBRARIES} ${FTGL_LIBRARIES}) - endif () - endif () -endmacro () - # append all files with extension "ext" in the "dirs" directories to "ret" # excludes all files starting with a '.' (dot) macro (acg_append_files ret ext) @@ -355,217 +158,11 @@ macro (acg_append_files ret ext) endforeach () endmacro () -# append all files with extension "ext" in the "dirs" directories and its subdirectories to "ret" -# excludes all files starting with a '.' (dot) -macro (acg_append_files_recursive ret ext) - foreach (_dir ${ARGN}) - file (GLOB_RECURSE _files "${_dir}/${ext}") - foreach (_file ${_files}) - get_filename_component (_filename ${_file} NAME) - if (_filename MATCHES "^[.]") - list (REMOVE_ITEM _files ${_file}) - endif () - endforeach () - list (APPEND ${ret} ${_files}) - endforeach () -endmacro () - - -# drop all "*T.cc" files from list -macro (acg_drop_templates list) - foreach (_file ${${list}}) - if (_file MATCHES "T.cc$") - list (REMOVE_ITEM ${list} ${_file}) - endif () - endforeach () -endmacro () - -# generate moc targets for sources in list -macro (acg_qt4_automoc moc_SRCS) - qt4_get_moc_flags (_moc_INCS) - - set (_matching_FILES ) - foreach (_current_FILE ${ARGN}) - - get_filename_component (_abs_FILE ${_current_FILE} ABSOLUTE) - # if "SKIP_AUTOMOC" is set to true, we will not handle this file here. - # here. this is required to make bouic work correctly: - # we need to add generated .cpp files to the sources (to compile them), - # but we cannot let automoc handle them, as the .cpp files don't exist yet when - # cmake is run for the very first time on them -> however the .cpp files might - # exist at a later run. at that time we need to skip them, so that we don't add two - # different rules for the same moc file - get_source_file_property (_skip ${_abs_FILE} SKIP_AUTOMOC) - - if ( NOT _skip AND EXISTS ${_abs_FILE} ) - - file (READ ${_abs_FILE} _contents) - - get_filename_component (_abs_PATH ${_abs_FILE} PATH) - - string (REGEX MATCHALL "Q_OBJECT" _match "${_contents}") - if (_match) - get_filename_component (_basename ${_current_FILE} NAME_WE) - set (_header ${_abs_FILE}) - set (_moc ${CMAKE_CURRENT_BINARY_DIR}/moc_${_basename}.cpp) - - add_custom_command (OUTPUT ${_moc} - COMMAND ${QT_MOC_EXECUTABLE} - ARGS ${_moc_INCS} ${_header} -o ${_moc} - DEPENDS ${_header} - ) - - add_file_dependencies (${_abs_FILE} ${_moc}) - set (${moc_SRCS} ${${moc_SRCS}} ${_moc}) - - endif () - endif () - endforeach () -endmacro () - -# generate moc targets for sources in list -macro (acg_qt5_automoc moc_SRCS) - qt5_get_moc_flags (_moc_INCS) - - list(REMOVE_DUPLICATES _moc_INCS) - - set (_matching_FILES ) - foreach (_current_FILE ${ARGN}) - - get_filename_component (_abs_FILE ${_current_FILE} ABSOLUTE) - # if "SKIP_AUTOMOC" is set to true, we will not handle this file here. - # here. this is required to make bouic work correctly: - # we need to add generated .cpp files to the sources (to compile them), - # but we cannot let automoc handle them, as the .cpp files don't exist yet when - # cmake is run for the very first time on them -> however the .cpp files might - # exist at a later run. at that time we need to skip them, so that we don't add two - # different rules for the same moc file - get_source_file_property (_skip ${_abs_FILE} SKIP_AUTOMOC) - - if ( NOT _skip AND EXISTS ${_abs_FILE} ) - - file (READ ${_abs_FILE} _contents) - - get_filename_component (_abs_PATH ${_abs_FILE} PATH) - - string (REGEX MATCHALL "Q_OBJECT" _match "${_contents}") - if (_match) - get_filename_component (_basename ${_current_FILE} NAME_WE) - set (_header ${_abs_FILE}) - set (_moc ${CMAKE_CURRENT_BINARY_DIR}/moc_${_basename}.cpp) - - add_custom_command (OUTPUT ${_moc} - COMMAND ${QT_MOC_EXECUTABLE} - ARGS ${_moc_INCS} ${_header} -o ${_moc} - DEPENDS ${_header} - ) - - add_file_dependencies (${_abs_FILE} ${_moc}) - set (${moc_SRCS} ${${moc_SRCS}} ${_moc}) - - endif () - endif () - endforeach () -endmacro () - -# generate uic targets for sources in list -macro (acg_qt4_autouic uic_SRCS) - - set (_matching_FILES ) - foreach (_current_FILE ${ARGN}) - - get_filename_component (_abs_FILE ${_current_FILE} ABSOLUTE) - - if ( EXISTS ${_abs_FILE} ) - - file (READ ${_abs_FILE} _contents) - - get_filename_component (_abs_PATH ${_abs_FILE} PATH) - - get_filename_component (_basename ${_current_FILE} NAME_WE) - string (REGEX REPLACE "Ui$" "" _cbasename ${_basename}) - set (_outfile ${CMAKE_CURRENT_BINARY_DIR}/ui_${_basename}.hh) - set (_header ${_basename}.hh) - set (_source ${_abs_PATH}/${_cbasename}.cc) - - add_custom_command (OUTPUT ${_outfile} - COMMAND ${QT_UIC_EXECUTABLE} - ARGS -o ${_outfile} ${_abs_FILE} - DEPENDS ${_abs_FILE}) - - add_file_dependencies (${_source} ${_outfile}) - set (${uic_SRCS} ${${uic_SRCS}} ${_outfile}) - - endif () - endforeach () -endmacro () - -# generate uic targets for sources in list -macro (acg_qt5_autouic uic_SRCS) - - set (_matching_FILES ) - foreach (_current_FILE ${ARGN}) - - get_filename_component (_abs_FILE ${_current_FILE} ABSOLUTE) - - if ( EXISTS ${_abs_FILE} ) - - file (READ ${_abs_FILE} _contents) - - get_filename_component (_abs_PATH ${_abs_FILE} PATH) - - get_filename_component (_basename ${_current_FILE} NAME_WE) - string (REGEX REPLACE "Ui$" "" _cbasename ${_basename}) - set (_outfile ${CMAKE_CURRENT_BINARY_DIR}/ui_${_basename}.hh) - set (_header ${_basename}.hh) - set (_source ${_abs_PATH}/${_cbasename}.cc) - - add_custom_command (OUTPUT ${_outfile} - COMMAND ${Qt5Widgets_UIC_EXECUTABLE} - ARGS -o ${_outfile} ${_abs_FILE} - MAIN_DEPENDENCY ${_abs_FILE} VERBATIM) - - add_file_dependencies (${_source} ${_outfile}) - set (${uic_SRCS} ${${uic_SRCS}} ${_outfile}) - - endif () - endforeach () -endmacro () - -# generate qrc targets for sources in list -macro (acg_qt4_autoqrc qrc_SRCS) - - set (_matching_FILES ) - foreach (_current_FILE ${ARGN}) - - get_filename_component (_abs_FILE ${_current_FILE} ABSOLUTE) - - if ( EXISTS ${_abs_FILE} ) - - file (READ ${_abs_FILE} _contents) - - get_filename_component (_abs_PATH ${_abs_FILE} PATH) - - get_filename_component (_basename ${_current_FILE} NAME_WE) - set (_outfile ${CMAKE_CURRENT_BINARY_DIR}/qrc_${_basename}.cpp) - - add_custom_command (OUTPUT ${_outfile} - COMMAND ${QT_RCC_EXECUTABLE} - ARGS -o ${_outfile} ${_abs_FILE} - DEPENDS ${_abs_FILE}) - - add_file_dependencies (${_source} ${_outfile}) - set (${qrc_SRCS} ${${qrc_SRCS}} ${_outfile}) - - endif () - endforeach () -endmacro () - # get all files in directory, but ignore svn macro (acg_get_files_in_dir ret dir) file (GLOB_RECURSE __files RELATIVE "${dir}" "${dir}/*") foreach (_file ${__files}) - if (NOT _file MATCHES ".*svn.*") + if ( (NOT _file MATCHES ".*svn.*") AND (NOT _file MATCHES ".DS_Store") ) list (APPEND ${ret} "${_file}") endif () endforeach () @@ -582,25 +179,13 @@ function (acg_copy_after_build target src dst) endforeach () endfunction () -# install the whole directory without svn files -function (acg_install_dir src dst) - acg_unset (_files) - acg_get_files_in_dir (_files ${src}) - foreach (_file ${_files}) - get_filename_component (_file_PATH ${_file} PATH) - install(FILES "${src}/${_file}" - DESTINATION "${dst}/${_file_PATH}" - ) - endforeach () -endfunction () - # extended version of add_executable that also copies output to out Build directory function (acg_add_executable _target) add_executable (${_target} ${ARGN}) # set common target properties defined in common.cmake acg_set_target_props (${_target}) - + if (WIN32 OR (APPLE AND NOT ACG_PROJECT_MACOS_BUNDLE)) add_custom_command (TARGET ${_target} POST_BUILD COMMAND ${CMAKE_COMMAND} -E @@ -656,7 +241,7 @@ function (acg_add_library _target _libtype) copy_if_different $ ${CMAKE_BINARY_DIR}/Build/${ACG_PROJECT_LIBDIR}/$) - add_custom_command (TARGET ${_target} POST_BUILD + add_custom_command (TARGET ${_target} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different $ @@ -671,22 +256,22 @@ function (acg_add_library _target _libtype) $ ${CMAKE_BINARY_DIR}/Build/${ACG_PROJECT_PLUGINDIR}/$) elseif (${_type} STREQUAL STATIC) - add_custom_command (TARGET ${_target} POST_BUILD + add_custom_command (TARGET ${_target} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different $ ${CMAKE_BINARY_DIR}/Build/${ACG_PROJECT_LIBDIR}/$) - endif() - - - # make an extra copy for windows into the binary directory + endif() + + + # make an extra copy for windows into the binary directory if (${_type} STREQUAL SHARED AND WIN32) add_custom_command (TARGET ${_target} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different $ ${CMAKE_BINARY_DIR}/Build/${ACG_PROJECT_BINDIR}/$) - endif () + endif () endif( (WIN32 AND MSVC) OR (APPLE AND NOT ACG_PROJECT_MACOS_BUNDLE)) @@ -720,57 +305,3 @@ function (acg_add_library _target _libtype) endfunction () -#generates qt translations -function (acg_add_translations _target _languages _sources) - - string (TOUPPER ${_target} _TARGET) - # generate/use translation files - # run with UPDATE_TRANSLATIONS set to on to build qm files - option (UPDATE_TRANSLATIONS_${_TARGET} "Update source translation *.ts files (WARNING: make clean will delete the source .ts files! Danger!)") - - set (_new_ts_files) - set (_ts_files) - - foreach (lang ${_languages}) - if (NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/translations/${_target}_${lang}.ts" OR UPDATE_TRANSLATIONS_${_TARGET}) - list (APPEND _new_ts_files "translations/${_target}_${lang}.ts") - else () - list (APPEND _ts_files "translations/${_target}_${lang}.ts") - endif () - endforeach () - - - set (_qm_files) - if ( _new_ts_files ) - qt4_create_translation(_qm_files ${_sources} ${_new_ts_files}) - endif () - - if ( _ts_files ) - qt4_add_translation(_qm_files2 ${_ts_files}) - list (APPEND _qm_files ${_qm_files2}) - endif () - - # create a target for the translation files ( and object files ) - # Use this target, to update only the translations - add_custom_target (translations_target_${_target} DEPENDS ${_qm_files}) - - # Build translations with the application - add_dependencies(${_target} translations_target_${_target} ) - - if (NOT EXISTS ${CMAKE_BINARY_DIR}/Build/${ACG_PROJECT_DATADIR}/Translations) - file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/Build/${ACG_PROJECT_DATADIR}/Translations ) - endif () - - foreach (_qm ${_qm_files}) - get_filename_component (_qm_name "${_qm}" NAME) - add_custom_command (TARGET translations_target_${_target} POST_BUILD - COMMAND ${CMAKE_COMMAND} -E - copy_if_different - ${_qm} - ${CMAKE_BINARY_DIR}/Build/${ACG_PROJECT_DATADIR}/Translations/${_qm_name}) - endforeach () - - if (NOT ACG_PROJECT_MACOS_BUNDLE OR NOT APPLE) - install (FILES ${_qm_files} DESTINATION "${ACG_PROJECT_DATADIR}/Translations") - endif () -endfunction () diff --git a/cmake/ACGCompiler.cmake b/cmake/ACGCompiler.cmake index 328157fe..464d4f49 100644 --- a/cmake/ACGCompiler.cmake +++ b/cmake/ACGCompiler.cmake @@ -19,7 +19,7 @@ if ( WIN32 ) list(APPEND ADDITIONAL_CMAKE_EXE_LINKER_FLAGS "/LARGEADDRESSAWARE" ) list(APPEND ADDITIONAL_CMAKE_SHARED_LINKER_FLAGS "/LARGEADDRESSAWARE" ) list(APPEND ADDITIONAL_CMAKE_MODULE_LINKER_FLAGS "/LARGEADDRESSAWARE" ) - endif() + endif() endif() @@ -45,10 +45,12 @@ endif( WIN32 ) if (UNIX) + set ( ADDITIONAL_CXX_FLAGS ) set ( ADDITIONAL_CXX_DEBUG_FLAGS ) set ( ADDITIONAL_CXX_RELEASE_FLAGS ) set ( ADDITIONAL_CXX_RELWITHDEBINFO_FLAGS ) + set ( ADDITIONAL_C_FLAGS ) set ( ADDITIONAL_C_DEBUG_FLAGS ) set ( ADDITIONAL_C_RELEASE_FLAGS ) set ( ADDITIONAL_C_RELWITHDEBINFO_FLAGS ) @@ -58,28 +60,13 @@ if (UNIX) ################################################################################ # add our standard flags for Template inclusion - list(APPEND ADDITIONAL_CXX_DEBUG_FLAGS "-DINCLUDE_TEMPLATES" ) - list(APPEND ADDITIONAL_CXX_RELEASE_FLAGS "-DINCLUDE_TEMPLATES" ) - list(APPEND ADDITIONAL_CXX_RELWITHDEBINFO_FLAGS "-DINCLUDE_TEMPLATES" ) - - # add our standard flags for Template inclusion - list(APPEND ADDITIONAL_C_DEBUG_FLAGS "-DINCLUDE_TEMPLATES" ) - list(APPEND ADDITIONAL_C_RELEASE_FLAGS "-DINCLUDE_TEMPLATES" ) - list(APPEND ADDITIONAL_C_RELWITHDEBINFO_FLAGS "-DINCLUDE_TEMPLATES" ) - -# Deprecated setting. Remove in future release, as the default template depth -# should be enough with state of the art compilers -# # Increase the template depth as this might be exceeded from time to time -# IF( NOT CMAKE_SYSTEM MATCHES "SunOS*") -# list(APPEND ADDITIONAL_CXX_DEBUG_FLAGS "-ftemplate-depth-100" ) -# list(APPEND ADDITIONAL_CXX_RELEASE_FLAGS "-ftemplate-depth-100" ) -# list(APPEND ADDITIONAL_CXX_RELWITHDEBINFO_FLAGS "-ftemplate-depth-100" ) -# ENDIF() + list(APPEND ADDITIONAL_CXX_FLAGS "-DINCLUDE_TEMPLATES" ) + list(APPEND ADDITIONAL_C_FLAGS "-DINCLUDE_TEMPLATES" ) ################################################################################ # OS Defines ################################################################################ - + if (APPLE) add_definitions( -DARCH_DARWIN ) endif() @@ -100,7 +87,7 @@ if (UNIX) ################################################################################ # Warnings ################################################################################ - + # Add the standard compiler warnings if ( NOT COMPILER_WARNINGS ) @@ -113,17 +100,27 @@ if (UNIX) set ( COMPILER_WARNINGS "" CACHE STRINGLIST "This list contains the warning flags used during compilation " ) ELSE () set ( COMPILER_WARNINGS "-W" "-Wall" "-Wno-unused" "-Wextra" "-Wno-variadic-macros" CACHE STRINGLIST "This list contains the warning flags used during compilation " ) - ENDIF() + ENDIF() endif ( NOT COMPILER_WARNINGS ) - list(APPEND ADDITIONAL_CXX_DEBUG_FLAGS ${COMPILER_WARNINGS} ) - list(APPEND ADDITIONAL_CXX_RELEASE_FLAGS ${COMPILER_WARNINGS} ) - list(APPEND ADDITIONAL_CXX_RELWITHDEBINFO_FLAGS ${COMPILER_WARNINGS} ) - - list(APPEND ADDITIONAL_C_DEBUG_FLAGS ${COMPILER_WARNINGS} ) - list(APPEND ADDITIONAL_C_RELEASE_FLAGS ${COMPILER_WARNINGS} ) - list(APPEND ADDITIONAL_C_RELWITHDEBINFO_FLAGS ${COMPILER_WARNINGS} ) + list(APPEND ADDITIONAL_CXX_FLAGS ${COMPILER_WARNINGS} ) + list(APPEND ADDITIONAL_C_FLAGS ${COMPILER_WARNINGS} ) + + + if ("${CMAKE_CXX_COMPILER}" MATCHES "Clang") + list(APPEND ADDITIONAL_CXX_FLAGS "-Weverything") + list(APPEND ADDITIONAL_CXX_FLAGS "-Wno-c++98-compat") + list(APPEND ADDITIONAL_CXX_FLAGS "-Wno-c++98-compat-pedantic") + list(APPEND ADDITIONAL_CXX_FLAGS "-Wno-padded") + list(APPEND ADDITIONAL_CXX_FLAGS "-Wno-old-style-cast") + list(APPEND ADDITIONAL_CXX_FLAGS "-Wno-documentation-unknown-command") + list(APPEND ADDITIONAL_CXX_FLAGS "-Wno-unreachable-code-return") + # enable later: + list(APPEND ADDITIONAL_CXX_FLAGS "-Wno-sign-conversion") + list(APPEND ADDITIONAL_CXX_FLAGS "-Wno-deprecated") + list(APPEND ADDITIONAL_CXX_FLAGS "-Wno-weak-vtables") + endif() ################################################################################ # STL Vector checks @@ -156,51 +153,51 @@ if (UNIX) ################################################################################ # Add the debug flags - foreach( flag ${ADDITIONAL_CXX_DEBUG_FLAGS} ) - if( NOT CMAKE_CXX_FLAGS_DEBUG MATCHES "${flag}" ) + foreach( flag ${ADDITIONAL_CXX_FLAGS} ${ADDITIONAL_CXX_DEBUG_FLAGS} ) + list (FIND ${CMAKE_CXX_FLAGS_DEBUG} ${flag} _index) + if (${_index} EQUAL -1) set( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${flag} ") endif() endforeach() # Add the release flags - foreach( flag ${ADDITIONAL_CXX_RELEASE_FLAGS} ) - if( NOT CMAKE_CXX_FLAGS_RELEASE MATCHES "${flag}" ) + foreach( flag ${ADDITIONAL_CXX_FLAGS} ${ADDITIONAL_CXX_RELEASE_FLAGS} ) + list (FIND ${CMAKE_CXX_FLAGS_RELEASE} ${flag} _index) + if (${_index} EQUAL -1) set( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${flag} ") endif() endforeach() # Add the release with debug info flags - foreach( flag ${ADDITIONAL_CXX_RELWITHDEBINFO_FLAGS} ) - if( NOT CMAKE_CXX_FLAGS_RELWITHDEBINFO MATCHES "${flag}" ) + foreach( flag ${ADDITIONAL_CXX_FLAGS} ${ADDITIONAL_CXX_RELWITHDEBINFO_FLAGS} ) + list (FIND ${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${flag} _index) + if (${_index} EQUAL -1) set( CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${flag} ") endif() endforeach() # Add the debug flags - foreach( flag ${ADDITIONAL_C_DEBUG_FLAGS} ) - if( NOT CMAKE_C_FLAGS_DEBUG MATCHES "${flag}" ) + foreach( flag ${ADDITIONAL_C_FLAGS} ${ADDITIONAL_C_DEBUG_FLAGS} ) + list (FIND ${CMAKE_C_FLAGS_DEBUG} ${flag} _index) + if (${_index} EQUAL -1) set( CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${flag} ") endif() endforeach() # Add the release flags - foreach( flag ${ADDITIONAL_C_RELEASE_FLAGS} ) - if( NOT CMAKE_C_FLAGS_RELEASE MATCHES "${flag}" ) + foreach( flag ${ADDITIONAL_C_FLAGS} ${ADDITIONAL_C_RELEASE_FLAGS} ) + list (FIND ${CMAKE_C_FLAGS_RELEASE} ${flag} _index) + if (${_index} EQUAL -1) set( CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${flag} ") endif() endforeach() # Add the release with debug info flags - foreach( flag ${ADDITIONAL_C_RELWITHDEBINFO_FLAGS} ) - if( NOT CMAKE_C_FLAGS_RELWITHDEBINFO MATCHES "${flag}" ) + foreach( flag ${ADDITIONAL_C_FLAGS} ${ADDITIONAL_C_RELWITHDEBINFO_FLAGS} ) + list (FIND ${CMAKE_C_FLAGS_RELWITHDEBINFO} ${flag} _index) + if (${_index} EQUAL -1) set( CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} ${flag} ") endif() endforeach() - #TODO : Test and remove it?! - IF( CMAKE_SYSTEM MATCHES "SunOS*") - set (CMAKE_CFLAGS_RELEASE "-xO3") - set (CMAKE_CXX_FLAGS_RELEASE "-xO3") - endif ( CMAKE_SYSTEM MATCHES "SunOS*" ) - endif () diff --git a/cmake/ACGDoxygen.cmake b/cmake/ACGDoxygen.cmake index e67b8fc6..bd6cc5f5 100644 --- a/cmake/ACGDoxygen.cmake +++ b/cmake/ACGDoxygen.cmake @@ -18,8 +18,9 @@ # author Jan Woetzel 2004-2006 # www.mip.informatik.uni-kiel.de/~jw - -FIND_PACKAGE(Doxygen) +if ( NOT DOXYGEN_FOUND) + FIND_PACKAGE(Doxygen) +endif() IF (DOXYGEN_FOUND) @@ -119,4 +120,4 @@ IF (DOXYGEN_FOUND) ENDIF(HTML_HELP_COMPILER) # MESSAGE(SEND_ERROR "HTML_HELP_COMPILER=${HTML_HELP_COMPILER}") ENDIF (WIN32) -ENDIF(DOXYGEN_FOUND) \ No newline at end of file +ENDIF(DOXYGEN_FOUND) diff --git a/cmake/ACGOutput.cmake b/cmake/ACGOutput.cmake index de488cf8..d06e298c 100644 --- a/cmake/ACGOutput.cmake +++ b/cmake/ACGOutput.cmake @@ -30,11 +30,13 @@ function (acg_print_configure_header _id _name) acg_color_message ("${_escape}[40;37m* Package : ${_escape}[32m${_project} ${_escape}[37m *${_escape}[0m") acg_color_message ("${_escape}[40;37m* Version : ${_escape}[32m${_version} ${_escape}[37m *${_escape}[0m") - # Just artistic. remove 2 spaces for release to make it look nicer ;-) - if (${CMAKE_BUILD_TYPE} MATCHES "Debug") - acg_color_message ("${_escape}[40;37m* Type : ${_escape}[32m${CMAKE_BUILD_TYPE} ${_escape}[37m *${_escape}[0m") - else() - acg_color_message ("${_escape}[40;37m* Type : ${_escape}[32m${CMAKE_BUILD_TYPE} ${_escape}[37m *${_escape}[0m") + if ( NOT WIN32 ) + # Just artistic. remove 2 spaces for release to make it look nicer ;-) + if (${CMAKE_BUILD_TYPE} MATCHES "Debug") + acg_color_message ("${_escape}[40;37m* Type : ${_escape}[32m${CMAKE_BUILD_TYPE} ${_escape}[37m *${_escape}[0m") + else() + acg_color_message ("${_escape}[40;37m* Type : ${_escape}[32m${CMAKE_BUILD_TYPE} ${_escape}[37m *${_escape}[0m") + endif() endif() acg_color_message ("${_escape}[40;37m************************************************************${_escape}[0m") diff --git a/cmake/ACGQt.cmake b/cmake/ACGQt.cmake new file mode 100644 index 00000000..c3e6ed67 --- /dev/null +++ b/cmake/ACGQt.cmake @@ -0,0 +1,105 @@ +macro (acg_qt5) + + #try to find qt5 automatically + #for custom installation of qt5, dont use any of these variables + set (QT5_INSTALL_PATH "" CACHE PATH "Path to Qt5 directory which contains lib and include folder") + + if (EXISTS "${QT5_INSTALL_PATH}") + set (CMAKE_PREFIX_PATH "${CMAKE_PREFIX_PATH};${QT5_INSTALL_PATH}") + set (QT5_INSTALL_PATH_EXISTS TRUE) + endif(EXISTS "${QT5_INSTALL_PATH}") + + set(QT5_FINDER_FLAGS "" CACHE STRING "Flags for the Qt finder e.g. + NO_DEFAULT_PATH if no system installed Qt shall be found") + # compute default search paths + set(SUPPORTED_QT_VERSIONS 5.11 5.10 5.9 5.8 5.7 5.6) + foreach (suffix gcc_64 clang_64) + foreach(version ${SUPPORTED_QT_VERSIONS}) + list(APPEND QT_DEFAULT_PATH "~/sw/Qt/${version}/${suffix}") + endforeach() + endforeach() + + find_package (Qt5Core PATHS ${QT_DEFAULT_PATH} ${QT5_FINDER_FLAGS}) + if(Qt5Core_FOUND) + + if(Qt5Core_VERSION) # use the new version variable if it is set + set(Qt5Core_VERSION_STRING ${Qt5Core_VERSION}) + endif(Qt5Core_VERSION) + + string(REGEX REPLACE "^([0-9]+)\\.[0-9]+\\.[0-9]+.*" "\\1" QT_VERSION_MAJOR "${Qt5Core_VERSION_STRING}") + string(REGEX REPLACE "^[0-9]+\\.([0-9]+)\\.[0-9]+.*" "\\1" QT_VERSION_MINOR "${Qt5Core_VERSION_STRING}") + string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" QT_VERSION_PATCH "${Qt5Core_VERSION_STRING}") + + find_package (Qt5Widgets QUIET PATHS ${QT_DEFAULT_PATH} ${QT5_FINDER_FLAGS}) + find_package (Qt5Gui QUIET PATHS ${QT_DEFAULT_PATH} ${QT5_FINDER_FLAGS}) + find_package (Qt5OpenGL QUIET PATHS ${QT_DEFAULT_PATH} ${QT5_FINDER_FLAGS}) + + if (NOT WIN32 AND NOT APPLE) + find_package (Qt5X11Extras QUIET PATHS ${QT_DEFAULT_PATH} ${QT5_FINDER_FLAGS}) + endif () + + if (Qt5Core_FOUND AND Qt5Widgets_FOUND AND Qt5Gui_FOUND AND Qt5OpenGL_FOUND ) + set (QT5_FOUND TRUE) + endif() + + endif(Qt5Core_FOUND) + + if (QT5_FOUND) + + #set plugin dir + list(GET Qt5Gui_PLUGINS 0 _plugin) + if (_plugin) + get_target_property(_plugin_full ${_plugin} LOCATION) + get_filename_component(_plugin_dir ${_plugin_full} PATH) + set (QT_PLUGINS_DIR "${_plugin_dir}/../" CACHE PATH "Path to the qt plugin directory") + elseif(QT5_INSTALL_PATH_EXISTS) + set (QT_PLUGINS_DIR "${QT5_INSTALL_PATH}/plugins/" CACHE PATH "Path to the qt plugin directory") + elseif() + set (QT_PLUGINS_DIR "QT_PLUGIN_DIR_NOT_FOUND" CACHE PATH "Path to the qt plugin directory") + endif(_plugin) + + #set binary dir for fixupbundle + if(QT5_INSTALL_PATH_EXISTS) + set(_QT_BINARY_DIR "${QT5_INSTALL_PATH}/bin") + else() + get_target_property(_QT_BINARY_DIR ${Qt5Widgets_UIC_EXECUTABLE} LOCATION) + get_filename_component(_QT_BINARY_DIR ${_QT_BINARY_DIR} PATH) + endif(QT5_INSTALL_PATH_EXISTS) + + set (QT_BINARY_DIR "${_QT_BINARY_DIR}" CACHE PATH "Qt5 binary Directory") + mark_as_advanced(QT_BINARY_DIR) + + set (CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) + + if (Qt5X11Extras_FOUND) + include_directories(${Qt5X11Extras_INCLUDE_DIRS}) + add_definitions(${Qt5X11Extras_DEFINITIONS}) + endif () + + if ( NOT MSVC ) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") + endif() + + #adding QT_NO_DEBUG to all release modes. + # Note: for multi generators like msvc you cannot set this definition depending of + # the current build type, because it may change in the future inside the ide and not via cmake + if (MSVC_IDE) + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /DQT_NO_DEBUG") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /DQT_NO_DEBUG") + + set(CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_RELEASE} /DQT_NO_DEBUG") + set(CMAKE_CXX_FLAGS_MINSITEREL "${CMAKE_C_FLAGS_RELEASE} /DQT_NO_DEBUG") + + set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELEASE} /DQT_NO_DEBUG") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELEASE} /DQT_NO_DEBUG") + else(MSVC_IDE) + if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug") + add_definitions(-DQT_NO_DEBUG) + endif() + endif(MSVC_IDE) + + # Enable automoc + set(CMAKE_AUTOMOC ON) + + endif (QT5_FOUND) +endmacro () diff --git a/cmake/FindEIGEN3.cmake b/cmake/FindEIGEN3.cmake new file mode 100644 index 00000000..fa8fc4f7 --- /dev/null +++ b/cmake/FindEIGEN3.cmake @@ -0,0 +1,70 @@ +# - Try to find EIGEN3 +# Once done this will define +# EIGEN3_FOUND - System has EIGEN3 +# EIGEN3_INCLUDE_DIRS - The EIGEN3 include directories + +if (EIGEN3_INCLUDE_DIR) + # in cache already + set(EIGEN3_FOUND TRUE) + set(EIGEN3_INCLUDE_DIRS "${EIGEN3_INCLUDE_DIR}" ) +else (EIGEN3_INCLUDE_DIR) + +# Check if the base path is set +if ( NOT CMAKE_WINDOWS_LIBS_DIR ) + # This is the base directory for windows library search used in the finders we shipp. + set(CMAKE_WINDOWS_LIBS_DIR "c:/libs" CACHE STRING "Default Library search dir on windows." ) +endif() + +if ( CMAKE_GENERATOR MATCHES "^Visual Studio 11.*Win64" ) + SET(VS_SEARCH_PATH "${CMAKE_WINDOWS_LIBS_DIR}/vs2012/x64/") +elseif ( CMAKE_GENERATOR MATCHES "^Visual Studio 11.*" ) + SET(VS_SEARCH_PATH "${CMAKE_WINDOWS_LIBS_DIR}/vs2012/x32/") +elseif ( CMAKE_GENERATOR MATCHES "^Visual Studio 12.*Win64" ) + SET(VS_SEARCH_PATH "${CMAKE_WINDOWS_LIBS_DIR}/vs2013/x64/") +elseif ( CMAKE_GENERATOR MATCHES "^Visual Studio 12.*" ) + SET(VS_SEARCH_PATH "${CMAKE_WINDOWS_LIBS_DIR}/vs2013/x32/") +elseif ( CMAKE_GENERATOR MATCHES "^Visual Studio 14.*Win64" ) + SET(VS_SEARCH_PATH "${CMAKE_WINDOWS_LIBS_DIR}/vs2015/x64/") +elseif ( CMAKE_GENERATOR MATCHES "^Visual Studio 14.*" ) + SET(VS_SEARCH_PATH "${CMAKE_WINDOWS_LIBS_DIR}/vs2015/x32/") +elseif ( CMAKE_GENERATOR MATCHES "^Visual Studio 15.*Win64" ) + SET(VS_SEARCH_PATH "${CMAKE_WINDOWS_LIBS_DIR}/vs2017/x64/") +elseif ( CMAKE_GENERATOR MATCHES "^Visual Studio 15.*" ) + SET(VS_SEARCH_PATH "${CMAKE_WINDOWS_LIBS_DIR}/vs2017/x32/") +endif() + + +find_path( EIGEN3_INCLUDE_DIR + NAMES Eigen/Dense + PATHS $ENV{EIGEN_DIR} + /usr/include/eigen3 + /usr/local/include + /usr/local/include/eigen3/ + /opt/local/include/eigen3/ + "${CMAKE_WINDOWS_LIBS_DIR}/general/Eigen-3.3.4" + "${CMAKE_WINDOWS_LIBS_DIR}/general/Eigen-3.2.8" + "${CMAKE_WINDOWS_LIBS_DIR}/general/Eigen-3.2.6" + "${CMAKE_WINDOWS_LIBS_DIR}/Eigen-3.2.6" + "${CMAKE_WINDOWS_LIBS_DIR}/Eigen-3.2.6/include" + "${CMAKE_WINDOWS_LIBS_DIR}/Eigen-3.2.1" + "${CMAKE_WINDOWS_LIBS_DIR}/Eigen-3.2.1/include" + "${CMAKE_WINDOWS_LIBS_DIR}/Eigen-3.2/include" + "${CMAKE_WINDOWS_LIBS_DIR}/eigen3/include" + "${CMAKE_WINDOWS_LIBS_DIR}/eigen/include" + ${PROJECT_SOURCE_DIR}/MacOS/Libs/eigen3/include + ../../External/include + ${module_file_path}/../../../External/include + ) + +set(EIGEN3_INCLUDE_DIRS "${EIGEN3_INCLUDE_DIR}" ) + + +include(FindPackageHandleStandardArgs) +# handle the QUIETLY and REQUIRED arguments and set LIBCPLEX_FOUND to TRUE +# if all listed variables are TRUE +find_package_handle_standard_args(EIGEN3 DEFAULT_MSG + EIGEN3_INCLUDE_DIR) + +mark_as_advanced(EIGEN3_INCLUDE_DIR) + +endif(EIGEN3_INCLUDE_DIR) diff --git a/cmake/FindGLEW.cmake b/cmake/FindGLEW.cmake deleted file mode 100644 index ff2d6a23..00000000 --- a/cmake/FindGLEW.cmake +++ /dev/null @@ -1,75 +0,0 @@ -# - Try to find GLEW -# Once done this will define -# -# GLEW_FOUND - system has GLEW -# GLEW_INCLUDE_DIR - the GLEW include directory -# GLEW_LIBRARY_DIR - where the libraries are -# GLEW_LIBRARY - Link these to use GLEW -# - -IF (GLEW_INCLUDE_DIR) - # Already in cache, be silent - SET(GLEW_FIND_QUIETLY TRUE) -ENDIF (GLEW_INCLUDE_DIR) - -if( WIN32 ) - - # Check if the base path is set - if ( NOT CMAKE_WINDOWS_LIBS_DIR ) - # This is the base directory for windows library search used in the finders we shipp. - set(CMAKE_WINDOWS_LIBS_DIR "c:\libs" CACHE STRING "Default Library search dir on windows." ) - endif() - - if ( CMAKE_GENERATOR MATCHES "^Visual Studio 11.*Win64" ) - SET(VS_SEARCH_PATH "${CMAKE_WINDOWS_LIBS_DIR}/vs2012/x64/") - elseif ( CMAKE_GENERATOR MATCHES "^Visual Studio 11.*" ) - SET(VS_SEARCH_PATH "${CMAKE_WINDOWS_LIBS_DIR}/vs2012/x32/") - elseif ( CMAKE_GENERATOR MATCHES "^Visual Studio 12.*Win64" ) - SET(VS_SEARCH_PATH "${CMAKE_WINDOWS_LIBS_DIR}/vs2013/x64/") - elseif ( CMAKE_GENERATOR MATCHES "^Visual Studio 12.*" ) - SET(VS_SEARCH_PATH "${CMAKE_WINDOWS_LIBS_DIR}/vs2013/x32/") - elseif ( CMAKE_GENERATOR MATCHES "^Visual Studio 14.*Win64" ) - SET(VS_SEARCH_PATH "${CMAKE_WINDOWS_LIBS_DIR}/vs2015/x64/") - elseif ( CMAKE_GENERATOR MATCHES "^Visual Studio 14.*" ) - SET(VS_SEARCH_PATH "${CMAKE_WINDOWS_LIBS_DIR}/vs2015/x32/") - endif() - - if( MSVC80 ) - set( COMPILER_PATH "C:/Program\ Files/Microsoft\ Visual\ Studio\ 8/VC" ) - endif( MSVC80 ) - if( MSVC71 ) - set( COMPILER_PATH "C:/Program\ Files/Microsoft\ Visual\ Studio\ .NET\ 2003/Vc7" ) - endif( MSVC71 ) - - FIND_PATH( GLEW_INCLUDE_DIR gl/glew.h gl/wglew.h - PATHS "${CMAKE_WINDOWS_LIBS_DIR}/glew/include" - "${CMAKE_WINDOWS_LIBS_DIR}/glew-1.6.0/include" - ${COMPILER_PATH}/PlatformSDK/Include - "${VS_SEARCH_PATH}glew-1.10.0/include") - - SET( GLEW_NAMES glew32 ) - FIND_LIBRARY( GLEW_LIBRARY - NAMES ${GLEW_NAMES} - PATHS "${CMAKE_WINDOWS_LIBS_DIR}/glew/lib" - "${CMAKE_WINDOWS_LIBS_DIR}/glew-1.6.0/lib" - ${COMPILER_PATH}/PlatformSDK/Lib - "${VS_SEARCH_PATH}glew-1.10.0/lib" ) - -else( WIN32 ) - FIND_PATH( GLEW_INCLUDE_DIR GL/glew.h GL/wglew.h - PATHS /usr/local/include /usr/include ) - SET( GLEW_NAMES glew GLEW ) - FIND_LIBRARY( GLEW_LIBRARY - NAMES ${GLEW_NAMES} - PATHS /usr/lib /usr/local/lib ) -endif( WIN32 ) - -GET_FILENAME_COMPONENT( GLEW_LIBRARY_DIR ${GLEW_LIBRARY} PATH ) - -IF (GLEW_INCLUDE_DIR AND GLEW_LIBRARY) - SET(GLEW_FOUND TRUE) -ELSE (GLEW_INCLUDE_DIR AND GLEW_LIBRARY) - SET( GLEW_FOUND FALSE ) - SET( GLEW_LIBRARY_DIR ) -ENDIF (GLEW_INCLUDE_DIR AND GLEW_LIBRARY) - diff --git a/cmake/FindGLUT.cmake b/cmake/FindGLUT.cmake deleted file mode 100644 index f3a99dfc..00000000 --- a/cmake/FindGLUT.cmake +++ /dev/null @@ -1,121 +0,0 @@ -# - try to find glut library and include files -# GLUT_INCLUDE_DIR, where to find GL/glut.h, etc. -# GLUT_LIBRARIES, the libraries to link against -# GLUT_FOUND, If false, do not try to use GLUT. -# Also defined, but not for general use are: -# GLUT_glut_LIBRARY = the full path to the glut library. -# GLUT_Xmu_LIBRARY = the full path to the Xmu library. -# GLUT_Xi_LIBRARY = the full path to the Xi Library. - -#============================================================================= -# Copyright 2001-2009 Kitware, Inc. -# -# Distributed under the OSI-approved BSD License (the "License"); -# see accompanying file Copyright.txt for details. -# -# This software is distributed WITHOUT ANY WARRANTY; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the License for more information. -#============================================================================= -# (To distributed this file outside of CMake, substitute the full -# License text for the above reference.) - -IF (WIN32) - - # Check if the base path is set - if ( NOT CMAKE_WINDOWS_LIBS_DIR ) - # This is the base directory for windows library search used in the finders we shipp. - set(CMAKE_WINDOWS_LIBS_DIR "c:\libs" CACHE STRING "Default Library search dir on windows." ) - endif() - - if ( CMAKE_GENERATOR MATCHES "^Visual Studio 11.*Win64" ) - SET(VS_SEARCH_PATH "${CMAKE_WINDOWS_LIBS_DIR}/vs2012/x64/") - elseif ( CMAKE_GENERATOR MATCHES "^Visual Studio 11.*" ) - SET(VS_SEARCH_PATH "${CMAKE_WINDOWS_LIBS_DIR}/vs2012/x32/") - elseif ( CMAKE_GENERATOR MATCHES "^Visual Studio 12.*Win64" ) - SET(VS_SEARCH_PATH "${CMAKE_WINDOWS_LIBS_DIR}/vs2013/x64/") - elseif ( CMAKE_GENERATOR MATCHES "^Visual Studio 12.*" ) - SET(VS_SEARCH_PATH "${CMAKE_WINDOWS_LIBS_DIR}/vs2013/x32/") - elseif ( CMAKE_GENERATOR MATCHES "^Visual Studio 14.*Win64" ) - SET(VS_SEARCH_PATH "${CMAKE_WINDOWS_LIBS_DIR}/vs2015/x64/") - elseif ( CMAKE_GENERATOR MATCHES "^Visual Studio 14.*" ) - SET(VS_SEARCH_PATH "${CMAKE_WINDOWS_LIBS_DIR}/vs2015/x32/") - endif() - - - FIND_PATH( GLUT_INCLUDE_DIR NAMES GL/glut.h - PATHS ${GLUT_ROOT_PATH}/include - "${CMAKE_WINDOWS_LIBS_DIR}/glut-3.7/include" - "${VS_SEARCH_PATH}/freeglut-3.0.0/include" - "${VS_SEARCH_PATH}/freeglut-2.8.1/include" ) - - FIND_LIBRARY( GLUT_glut_LIBRARY NAMES glut32 glut freeglut - PATHS - ${OPENGL_LIBRARY_DIR} - ${GLUT_ROOT_PATH}/Release - "${CMAKE_WINDOWS_LIBS_DIR}/glut-3.7/lib" - "${VS_SEARCH_PATH}/freeglut-3.0.0/lib" - "${VS_SEARCH_PATH}/freeglut-2.8.1/lib" - ) - - GET_FILENAME_COMPONENT( GLUT_LIBRARY_DIR ${GLUT_glut_LIBRARY} PATH ) - -ELSE (WIN32) - - IF (APPLE) - # These values for Apple could probably do with improvement. - FIND_PATH( GLUT_INCLUDE_DIR glut.h - /System/Library/Frameworks/GLUT.framework/Versions/A/Headers - ${OPENGL_LIBRARY_DIR} - ) - SET(GLUT_glut_LIBRARY "-framework GLUT" CACHE STRING "GLUT library for OSX") - SET(GLUT_cocoa_LIBRARY "-framework Cocoa" CACHE STRING "Cocoa framework for OSX") - ELSE (APPLE) - - FIND_PATH( GLUT_INCLUDE_DIR GL/glut.h - /usr/include/GL - /usr/openwin/share/include - /usr/openwin/include - /opt/graphics/OpenGL/include - /opt/graphics/OpenGL/contrib/libglut - ) - - FIND_LIBRARY( GLUT_glut_LIBRARY glut - /usr/openwin/lib - ) - - FIND_LIBRARY( GLUT_Xi_LIBRARY Xi - /usr/openwin/lib - ) - - FIND_LIBRARY( GLUT_Xmu_LIBRARY Xmu - /usr/openwin/lib - ) - - ENDIF (APPLE) - -ENDIF (WIN32) - -SET( GLUT_FOUND "NO" ) -IF(GLUT_INCLUDE_DIR) - IF(GLUT_glut_LIBRARY) - - SET( GLUT_LIBRARIES - ${GLUT_glut_LIBRARY} - ${GLUT_cocoa_LIBRARY} - ) - SET( GLUT_FOUND "YES" ) - - #The following deprecated settings are for backwards compatibility with CMake1.4 - SET (GLUT_LIBRARY ${GLUT_LIBRARIES}) - SET (GLUT_INCLUDE_PATH ${GLUT_INCLUDE_DIR}) - - ENDIF(GLUT_glut_LIBRARY) -ENDIF(GLUT_INCLUDE_DIR) - -MARK_AS_ADVANCED( - GLUT_INCLUDE_DIR - GLUT_glut_LIBRARY - GLUT_Xmu_LIBRARY - GLUT_Xi_LIBRARY - ) diff --git a/cmake/FindGoogleTest.cmake b/cmake/FindGoogleTest.cmake deleted file mode 100644 index 6918c7d9..00000000 --- a/cmake/FindGoogleTest.cmake +++ /dev/null @@ -1,116 +0,0 @@ -# Locate and configure the Google Test libraries. -# -# Defines the following variable: -# -# GTEST_FOUND - Found the Google Test libraries -# GTEST_INCLUDE_DIRS - The directories needed on the include paths -# GTEST_LIBRARIES - The libraries to link to test executables -# GTEST_MAIN_LIBRARIES - The libraries to link for automatic main() provision -# -# Copyright 2008 Chandler Carruth -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may not -# use this file except in compliance with the License. You may obtain a copy -# of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -if(GTEST_INCLUDE_DIRS AND GTEST_LIBRARIES AND GTEST_MAIN_LIBRARIES) - set(GTEST_FOUND true) -else(GTEST_INCLUDE_DIRS AND GTEST_LIBRARIES AND GTEST_MAIN_LIBRARIES) - set(GTEST_PREFIX "" CACHE PATH "Installation prefix for Google Test") - if(GTEST_PREFIX) - find_path(_GTEST_INCLUDE_DIR "gtest/gtest.h" - PATHS "${GTEST_PREFIX}/include" - NO_DEFAULT_PATH) - find_library(_GTEST_LIBRARY gtest - PATHS "${GTEST_PREFIX}/lib" - NO_DEFAULT_PATH) - find_library(_GTEST_MAIN_LIBRARY gtest_main - PATHS "${GTEST_PREFIX}/lib" - NO_DEFAULT_PATH) - - if ( _GTEST_LIBRARY ) - get_filename_component(_GTEST_LIBRARY_DIR ${_GTEST_LIBRARY} PATH CACHE ) - endif() - else(GTEST_PREFIX) - find_path(_GTEST_INCLUDE_DIR "gtest/gtest.h" - PATHS - ~/sw/gtest-1.8.0/include - ~/sw/gtest-1.7.0/include - ~/sw/gtest/include - /ACG/acgdev/gcc-x86_64/gtest/include - /opt/local/include - /usr/local/include - /usr/include - "C:/libs/win32/gtest/include" - NO_DEFAULT_PATH ) - find_library(_GTEST_LIBRARY gtest - PATHS - ~/sw/gtest-1.8.0/lib - ~/sw/gtest-1.7.0/lib - ~/sw/gtest/lib - /ACG/acgdev/gcc-x86_64/gtest/lib - /opt/local/lib - /usr/local/lib - /usr/lib - "C:/libs/win32/gtest/lib" - NO_DEFAULT_PATH ) - find_library(_GTEST_MAIN_LIBRARY gtest_main - PATHS - ~/sw/gtest-1.8.0/lib - ~/sw/gtest-1.7.0/lib - ~/sw/gtest/lib - /ACG/acgdev/gcc-x86_64/gtest/lib - /opt/local/lib - /usr/local/lib - /usr/lib - "C:/libs/win32/gtest/lib" - NO_DEFAULT_PATH ) - - if ( _GTEST_LIBRARY ) - get_filename_component(_GTEST_LIBRARY_DIR ${_GTEST_LIBRARY} PATH CACHE ) - endif() - - endif(GTEST_PREFIX) - if(_GTEST_INCLUDE_DIR AND _GTEST_LIBRARY AND _GTEST_MAIN_LIBRARY) - set(GTEST_FOUND true) - set(GTEST_INCLUDE_DIRS ${_GTEST_INCLUDE_DIR} CACHE PATH - "Include directories for Google Test framework") - - if ( NOT WIN32 ) - set(GTEST_LIBRARIES ${_GTEST_LIBRARY} CACHE FILEPATH - "Libraries to link for Google Test framework") - set(GTEST_MAIN_LIBRARIES ${_GTEST_MAIN_LIBRARY} CACHE FILEPATH - "Libraries to link for Google Test automatic main() definition") - else() - set(GTEST_LIBRARIES "optimized;gtest;debug;gtestd" CACHE FILEPATH - "Libraries to link for Google Test framework") - set(GTEST_MAIN_LIBRARIES "optimized;gtest_main;debug;gtest_maind" CACHE FILEPATH - "Libraries to link for Google Test automatic main() definition") - endif() - - # Macro required to use google test with vs2012 - if ( CMAKE_GENERATOR MATCHES "^Visual Studio 11.*" ) - add_definitions(-D_VARIADIC_MAX=10) - endif() - - - set(GTEST_LIBRARY_DIR ${_GTEST_LIBRARY_DIR} CACHE FILEPATH - "Library dir containing Google Test libraries") - mark_as_advanced(GTEST_INCLUDE_DIRS GTEST_LIBRARIES GTEST_MAIN_LIBRARIES GTEST_LIBRARY_DIR ) - if(NOT GoogleTest_FIND_QUIETLY) - message(STATUS "Found Google Test: ${GTEST_LIBRARIES}") - endif(NOT GoogleTest_FIND_QUIETLY) - else(_GTEST_INCLUDE_DIR AND _GTEST_LIBRARY AND _GTEST_MAIN_LIBRARY) - if(GoogleTest_FIND_REQUIRED) - message(FATAL_ERROR "Could not find the Google Test framework") - endif(GoogleTest_FIND_REQUIRED) - endif(_GTEST_INCLUDE_DIR AND _GTEST_LIBRARY AND _GTEST_MAIN_LIBRARY) -endif(GTEST_INCLUDE_DIRS AND GTEST_LIBRARIES AND GTEST_MAIN_LIBRARIES) diff --git a/cmake/FindOpenMP.cmake b/cmake/FindOpenMP.cmake deleted file mode 100644 index 5e8980de..00000000 --- a/cmake/FindOpenMP.cmake +++ /dev/null @@ -1,108 +0,0 @@ -# - Finds OpenMP support -# This module can be used to detect OpenMP support in a compiler. -# If the compiler supports OpenMP, the flags required to compile with -# openmp support are set. -# -# The following variables are set: -# OpenMP_C_FLAGS - flags to add to the C compiler for OpenMP support -# OpenMP_CXX_FLAGS - flags to add to the CXX compiler for OpenMP support -# OPENMP_FOUND - true if openmp is detected -# -# Supported compilers can be found at http://openmp.org/wp/openmp-compilers/ - - -# Copyright 2008, 2009 Andre.Brodtkorb@ifi.uio.no -# -# Redistribution AND use is allowed according to the terms of the New -# BSD license. -# For details see the accompanying COPYING-CMAKE-SCRIPTS file. - - -include(CheckCSourceCompiles) -include(CheckCXXSourceCompiles) -include(FindPackageHandleStandardArgs) - -set(OpenMP_C_FLAG_CANDIDATES - #Gnu - "-fopenmp" - #Microsoft Visual Studio - "/openmp" - #Intel windows - "-Qopenmp" - #Intel - "-openmp" - #Empty, if compiler automatically accepts openmp - " " - #Sun - "-xopenmp" - #HP - "+Oopenmp" - #IBM XL C/c++ - "-qsmp" - #Portland Group - "-mp" -) -set(OpenMP_CXX_FLAG_CANDIDATES ${OpenMP_C_FLAG_CANDIDATES}) - -# sample openmp source code to test -set(OpenMP_C_TEST_SOURCE -" -#include -int main() { -#ifdef _OPENMP - return 0; -#else - breaks_on_purpose -#endif -} -") -# use the same source for CXX as C for now -set(OpenMP_CXX_TEST_SOURCE ${OpenMP_C_TEST_SOURCE}) -# if these are set then do not try to find them again, -# by avoiding any try_compiles for the flags -if(DEFINED OpenMP_C_FLAGS AND DEFINED OpenMP_CXX_FLAGS) - set(OpenMP_C_FLAG_CANDIDATES) - set(OpenMP_CXX_FLAG_CANDIDATES) -endif(DEFINED OpenMP_C_FLAGS AND DEFINED OpenMP_CXX_FLAGS) - -# check c compiler -foreach(FLAG ${OpenMP_C_FLAG_CANDIDATES}) - set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") - set(CMAKE_REQUIRED_FLAGS "${FLAG}") - set(OpenMP_C_FLAG_DETECTED) - message(STATUS "Try OpenMP C flag = [${FLAG}]") - check_c_source_compiles("${OpenMP_CXX_TEST_SOURCE}" OpenMP_C_FLAG_DETECTED) - set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}") - if(OpenMP_C_FLAG_DETECTED) - set(OpenMP_C_FLAGS_INTERNAL "${FLAG}") - break() - endif(OpenMP_C_FLAG_DETECTED) -endforeach(FLAG ${OpenMP_C_FLAG_CANDIDATES}) - -# check cxx compiler -foreach(FLAG ${OpenMP_CXX_FLAG_CANDIDATES}) - set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") - set(CMAKE_REQUIRED_FLAGS "${FLAG}") - set(OpenMP_CXX_FLAG_DETECTED) - message(STATUS "Try OpenMP CXX flag = [${FLAG}]") - check_cxx_source_compiles("${OpenMP_C_TEST_SOURCE}" OpenMP_CXX_FLAG_DETECTED) - set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}") - if(OpenMP_CXX_FLAG_DETECTED) - set(OpenMP_CXX_FLAGS_INTERNAL "${FLAG}") - break() - endif(OpenMP_CXX_FLAG_DETECTED) -endforeach(FLAG ${OpenMP_CXX_FLAG_CANDIDATES}) - -set(OpenMP_C_FLAGS "${OpenMP_C_FLAGS_INTERNAL}" - CACHE STRING "C compiler flags for OpenMP parallization") - -set(OpenMP_CXX_FLAGS "${OpenMP_CXX_FLAGS_INTERNAL}" - CACHE STRING "C++ compiler flags for OpenMP parallization") -# handle the standard arguments for find_package -find_package_handle_standard_args(OpenMP DEFAULT_MSG - OpenMP_C_FLAGS OpenMP_CXX_FLAGS ) - -mark_as_advanced( - OpenMP_C_FLAGS - OpenMP_CXX_FLAGS -) diff --git a/cmake/FindOpenMesh.cmake b/cmake/FindOpenMesh.cmake index 693b1517..9f03a063 100644 --- a/cmake/FindOpenMesh.cmake +++ b/cmake/FindOpenMesh.cmake @@ -63,6 +63,10 @@ IF (NOT OPENMESH_FOUND) "${CMAKE_SOURCE_DIR}/OpenMesh/src/OpenMesh" "${CMAKE_SOURCE_DIR}/libs_required/OpenMesh/src/OpenMesh" "${CMAKE_SOURCE_DIR}/../OpenMesh/src/OpenMesh" + "C:/Program Files/OpenMesh 8.1" + "C:/Program Files/OpenMesh 8.0" + "C:/Program Files/OpenMesh 7.2" + "C:/Program Files/OpenMesh 7.1" "C:/Program Files/OpenMesh 7.0" "C:/Program Files/OpenMesh 6.3" "C:/Program Files/OpenMesh 6.2" @@ -82,6 +86,9 @@ IF (NOT OPENMESH_FOUND) "C:/Program Files/OpenMesh 2.4.1" "C:/Program Files/OpenMesh 2.4" "C:/Program Files/OpenMesh 2.0/include" + "C:/libs/OpenMesh 8.1" + "C:/libs/OpenMesh 8.0" + "C:/libs/OpenMesh 7.1" "C:/libs/OpenMesh 7.0" "C:/libs/OpenMesh 6.3" "C:/libs/OpenMesh 6.2" diff --git a/cmake/fixbundle.cmake.in b/cmake/fixbundle.cmake.in index 571dfa19..32d82670 100644 --- a/cmake/fixbundle.cmake.in +++ b/cmake/fixbundle.cmake.in @@ -53,9 +53,6 @@ include (BundleUtilities) # list(APPEND _qtdirs "${_dir}") # endforeach () -# # Get library paths -# get_filename_component(_GlutDir "@GLUT_glut_LIBRARY@" PATH) - # # fix all dependencies # fixup_bundle (@CMAKE_BINARY_DIR@/Build/bin/QtViewer "${_qtplugins}" "/usr/lib;${_qtdirs};${_GlutDir}") # diff --git a/cmake/fixbundle.cmake.win.in b/cmake/fixbundle.cmake.win.in index 55c42341..eb73318e 100644 --- a/cmake/fixbundle.cmake.win.in +++ b/cmake/fixbundle.cmake.win.in @@ -17,11 +17,8 @@ endfunction(gp_item_default_embedded_path_override) include (BundleUtilities) -# Get library paths -get_filename_component(_GlutDir "@GLUT_glut_LIBRARY@" PATH) - # fix all dependencies -fixup_bundle ("@CMAKE_BINARY_DIR@/Build/Smoothing.exe" "" "${_GlutDir};@QT_BINARY_DIR@") +fixup_bundle ("@CMAKE_BINARY_DIR@/Build/Smoothing.exe" "" "@QT_BINARY_DIR@") diff --git a/openmesh.pc.in b/openmesh.pc.in new file mode 100644 index 00000000..99c3437d --- /dev/null +++ b/openmesh.pc.in @@ -0,0 +1,11 @@ +prefix=@DEST_DIR@ +exec_prefix=${prefix} +libdir=${prefix}/lib +includedir=${prefix}/include + +Name: libOpenMesh +Description: OpenMesh library +Version: @OPENMESH_VERSION_MAJOR@.@OPENMESH_VERSION_MINOR@ + +Libs: -L${libdir} @PRIVATE_LIBS@ +Cflags: -I${includedir} diff --git a/qmake/all.include b/qmake/all.include deleted file mode 100644 index 551272e3..00000000 --- a/qmake/all.include +++ /dev/null @@ -1,134 +0,0 @@ - -################################################################################ -# This is a library -################################################################################ - - -################################################################################ -# Needed Qt packages and build plugin -################################################################################ - -CONFIG += qt uitools opengl thread debug_and_release - -QT += opengl - -################################################################################ -# Add toplevel directory to include path -# TOPDIR has to be specified in a .qmake.cache file in your projects toplevel -# directory -################################################################################ -INCLUDEPATH = $$quote( $$TOPDIR/src ) -DEPENDPATH = $$quote( $${TOPDIR}/src ) - -################################################################################ -# Define header Extension -# This will also override the header extension for uic output -# ( Do not change to += otherwise uic output will end with .h ! ) -################################################################################ -QMAKE_EXT_H = .hh .h - -################################################################################ -# Architecture detection -################################################################################ -include( architecture.include ) - -################################################################################ -# Helper functions -################################################################################ -include( functions.include ) - -################################################################################ -# Custom settings for compiler flags and similar -################################################################################ -include( compiler.include) - -################################################################################ -# Extra target definitions -################################################################################ -include( targets.include ) - -################################################################################ -# Global package definitions -################################################################################ -include( packages/packages.$${SYSTEMTYPE} ) - -################################################################################ -# Local package definitions -# These lines will include a file from a .qmake directory inside your home. -# this file will overwrite existing setting -################################################################################ - -unix { - HOME=$$system(echo ~) -} -#else { - #message( TODO : Define Home in Windows ) -#} - -exists( $${HOME}/.qmake/config.$${SYSTEMTYPE} ) { - include( $${HOME}/.qmake/config.$${SYSTEMTYPE} ) -} - -################################################################################ -# Set standard build directories -# ( Everything generated while compiling will go # into a per architecture -# directory ) -################################################################################ -OBJECTS_DIR = tmp/$$BUILDDIRECTORY -MOC_DIR = tmp/$$BUILDDIRECTORY -UI_DIR = tmp/$$BUILDDIRECTORY - -################################################################################ -# type definitions -################################################################################ - -defineTest(Library) { - unix{ - TEMPLATE = lib - contains( OPERATING_SYSTEM, Darwin) { - CONFIG -= static - export(CONFIG) - } - } - win32 { - TEMPLATE = vclib - } - export(TEMPLATE) - DESTDIR = lib/$$BUILDDIRECTORY - export(DESTDIR) - defineTargets() - UI_DIR = include - export(UI_DIR) -} - -defineTest(Application) { - unix { - TEMPLATE = app - } - win32 { - TEMPLATE = vcapp - } - macx { - CONFIG -= app_bundle - export( CONFIG ) - } - export(TEMPLATE) - DESTDIR = $$BUILDDIRECTORY - export(DESTDIR) - defineTargets() -} - - -defineTest(Subdirs) { - unix { - TEMPLATE = subdirs - } - win32 { - TEMPLATE = vcsubdirs - } - export(TEMPLATE) - CONFIG += ordered - export(CONFIG) - defineTargets() -} - diff --git a/qmake/architecture.include b/qmake/architecture.include deleted file mode 100644 index 369ff027..00000000 --- a/qmake/architecture.include +++ /dev/null @@ -1,87 +0,0 @@ - -################################################################################ -# Architecture detection -# The following Variables are defined by this include: -# OPERATING_SYSTEM : Debian / Fedora / Windows -# ARCHITECTURE : 32 / 64 -# MODE : Debug / Release -# BUILDDIRECTORY : Concat of all above variables sesparated by underscores e.g. Debian_64_debug -################################################################################ - -unix { - - OPERATING_SYSTEM = UNKNOWN_OS - - exists( /etc/lsb-release ) { - OPERATING_SYSTEM = Ubuntu - } - - - exists( /etc/debian_version ) | exists( /etc/debian_release ) { - OPERATING_SYSTEM = Debian - } - - exists( /etc/fedora-release ) { - OPERATING_SYSTEM = Fedora - } - - exists( /etc/gentoo-release ) { - OPERATING_SYSTEM = Gentoo - } - - exists( /etc/lfs-release ) { - OPERATING_SYSTEM = Linux_From_Scratch - } - - exists( /etc/mandrake-release ) | exists( /etc/mandrakelinux-release ) { - OPERATING_SYSTEM = Mandrake - } - - exists( /etc/mandriva-release ) { - OPERATING_SYSTEM = Mandriva - } - - exists( /etc/redhat-release ) | exists( /etc/redhat_version ) { - OPERATING_SYSTEM = Redhat - } - - exists( /etc/SuSE-release ) | exists( /etc/novell-release ) { - OPERATING_SYSTEM = SuSE - } - - TEST_DARWIN = $$system(uname -s) - contains( TEST_DARWIN, Darwin) { - OPERATING_SYSTEM = Darwin - DEFINES += ARCH_DARWIN - export(DEFINES) - } - - HARDWARE_PLATFORM = $$system(uname -a) - contains( HARDWARE_PLATFORM, x86_64 ) { - # 64-bit Linux - ARCHITECTURE = 64 - } else { - # 32-bit Linux - ARCHITECTURE = 32 - } - - contains(TEST_DARWIN, Darwin) { - SYSTEMTYPE = Darwin - } else { - SYSTEMTYPE = Linux - } -} - -win32 { - OPERATING_SYSTEM = Windows - ARCHITECTURE = 32 - SYSTEMTYPE = Windows -} - -CONFIG( debug, debug|release ){ - MODE = Debug -} else { - MODE = Release -} - -BUILDDIRECTORY = $${OPERATING_SYSTEM}_$${ARCHITECTURE}_$${MODE} diff --git a/qmake/compiler.include b/qmake/compiler.include deleted file mode 100644 index 88a4b8be..00000000 --- a/qmake/compiler.include +++ /dev/null @@ -1,18 +0,0 @@ -################################################################################ -# Custom settings for compiler flags and similar -################################################################################ - -unix { - QMAKE_CC = gcc-4.3 - QMAKE_CXX = g++-4.3 - macx { - QMAKE_CC = gcc-4.0 - QMAKE_CXX = g++-4.0 - } - - QMAKE_CFLAGS_RELEASE = -O3 -DINCLUDE_TEMPLATES -W -Wall -Wno-unused -DNDEBUG - QMAKE_CXXFLAGS_RELEASE = -O3 -DINCLUDE_TEMPLATES -ftemplate-depth-100 -W -Wall -Wno-unused -DNDEBUG - QMAKE_CFLAGS_DEBUG = -g -DINCLUDE_TEMPLATES -W -Wall -Wno-unused -DDEBUG - QMAKE_CXXFLAGS_DEBUG = -g -DINCLUDE_TEMPLATES -ftemplate-depth-100 -W -Wall -Wno-unused -DDEBUG -} - diff --git a/qmake/functions.include b/qmake/functions.include deleted file mode 100644 index 5e5771c6..00000000 --- a/qmake/functions.include +++ /dev/null @@ -1,76 +0,0 @@ - -################################################################################ -# functions collecting all headers in the directory -################################################################################ - -# getFilesFromDir( directory, pattern ) -# returns a list of all files matching pattern in directory -defineReplace(getFilesFromDir) { - dirs = $$1 - pattern = $$2 - - files = - - for(dir, dirs) { - found = $$files( $${dir}/$${pattern} ) - files += $$found - } - - return( $$files ) -} - -# addSubdirs(subdirs,deps): Adds directories to the project that depend on -# other directories -defineTest( addSubdirs ) { - for(subdirs, 1) { - entries = $$files($$subdirs) - for(entry, entries) { - name = $$replace(entry, [/\\\\], _) - name = $$replace(name, - , _) - SUBDIRS += $$name - eval ($${name}.subdir = $$entry) - for(dep, 2): { - tempval = $$replace(dep, [/\\\\], _) - eval ($${name}.depends += $$replace(tempval, - , _) ) - } - export ($${name}.subdir) - export ($${name}.depends) - } - } - export (SUBDIRS) -} - -# given a list of paths and a libname this function checks if the lib is there -# adds the path and returns true if found otherwise false -defineTest( addLib ) { - dirs = $$1 - name = $$2 - - # check for the library - for(dir , dirs) { - check = $${dir}/lib$${name}.so - - # Found, so use it - exists( $$check ) { - LIBS *= -L$${dir} -l$$name - export(LIBS) - return(true) - } - } - - return(false) -} - - -defineReplace( getCurrentDir ) { - DIR = '' - unix { - DIR = $$system( pwd ) - } - - win32 { - DIR = $$system( cd ) - } - - return( $$DIR ) -} diff --git a/qmake/packages/packages.Darwin b/qmake/packages/packages.Darwin deleted file mode 100644 index 874f67af..00000000 --- a/qmake/packages/packages.Darwin +++ /dev/null @@ -1,38 +0,0 @@ - -################################################################################ -# INCLUDE Packages -################################################################################ - -defineTest( qt ) { - QT += opengl network script sql - export(QT) -} - -defineTest( glew ) { - INCLUDEPATH *= /sw/include/GL - export(INCLUDEPATH) - LIBS *= -L/opt/local/lib/ -lGLEW - export(LIBS) -} - -defineTest( glut ) { - INCLUDEPATH *= /System/Library/Frameworks/GLUT.framework/Headers - export(INCLUDEPATH) - LIBS *= -framework GLUT - export(LIBS) -} - -defineTest( openmesh ) { - QMAKE_LIBDIR += $${TOPDIR}/lib - QMAKE_LIBDIR += $${TOPDIR}/lib - - CONFIG( debug, debug|release ){ - LIBS += -lOpenMeshToolsd - LIBS += -lOpenMeshCored - } else { - LIBS += -lOpenMeshTools - LIBS += -lOpenMeshCore - } - export(QMAKE_LIBDIR) - export(LIBS) -} diff --git a/qmake/packages/packages.Linux b/qmake/packages/packages.Linux deleted file mode 100644 index a71bf22f..00000000 --- a/qmake/packages/packages.Linux +++ /dev/null @@ -1,71 +0,0 @@ - -################################################################################ -# INCLUDE Packages -################################################################################ - -defineTest( qt ) { - CONFIG *= uitools - export(CONFIG) - QT += opengl network script sql - export(QT) -} - -defineTest( qwt ) { - INCLUDEPATH *= /usr/include/qwt-qt4/ - export(INCLUDEPATH) - LIBS *= -L/usr/lib/ -lqwt-qt4 - export(LIBS) -} - -defineTest( glew ) { - INCLUDEPATH *= /usr/include/GL - export(INCLUDEPATH) - LIBS *= -L/usr/lib -lGLEW - export(LIBS) -} - -defineTest( glut ) { - INCLUDEPATH *=$${ACG}/OpenGL/include - export(INCLUDEPATH) - LIBS *= -L/usr/X11R6/lib -lglut - export(LIBS) -} - -defineTest( openmesh ) { - QMAKE_LIBDIR += $${TOPDIR}/lib/ - QMAKE_LIBDIR += $${TOPDIR}/lib/ - - CONFIG( debug, debug|release ){ - LIBS+= -Wl,-rpath=$${TOPDIR}/lib -lOpenMeshCored - LIBS+= -Wl,-rpath=$${TOPDIR}/lib -lOpenMeshToolsd - } else { - LIBS+= -Wl,-rpath=$${TOPDIR}/lib -lOpenMeshCore - LIBS+= -Wl,-rpath=$${TOPDIR}/lib -lOpenMeshTools - } - - export(QMAKE_LIBDIR) - export(LIBS) -} - -defineTest( openmp ) { - - addLib( /usr/lib/gcc/x86_64-linux-gnu/4.3 /usr/lib, gomp ) { - - QMAKE_CXXFLAGS_RELEASE += -fopenmp - QMAKE_CXXFLAGS_DEBUG += -fopenmp - QMAKE_CFLAGS_RELEASE += -fopenmp - QMAKE_CFLAGS_DEBUG += -fopenmp - QMAKE_LFLAGS_DEBUG += -fopenmp - QMAKE_LFLAGS_RELEASE += -fopenmp - - export(QMAKE_CXXFLAGS_RELEASE) - export(QMAKE_CFLAGS_RELEASE) - export(QMAKE_CXXFLAGS_DEBUG) - export(QMAKE_CFLAGS_DEBUG) - export(QMAKE_LFLAGS_DEBUG) - export(QMAKE_LFLAGS_RELEASE) - } else { - message("Unable to find OpenMP lib for linking. OpenMP support will be disabled!!") - } - -} diff --git a/qmake/packages/packages.Windows b/qmake/packages/packages.Windows deleted file mode 100644 index a397be34..00000000 --- a/qmake/packages/packages.Windows +++ /dev/null @@ -1,77 +0,0 @@ - -################################################################################ -# INCLUDE Packages -################################################################################ - - -defineTest( glew ) { - - ####################################### - ## Enter here the correct path to GLEW - ####################################### - - GLEW_PATH = c:\libs\glew - - ####################################### - - !exists ( $${GLEW_PATH} ) { - error (ERROR: GLEW not found or wrong path entry in OpenMesh\qmake\packages\packages.Windows! Please adjust it to your path!) - } - INCLUDEPATH *= $${GLEW_PATH}\include - export(INCLUDEPATH) - LIBS *= -L$${GLEW_PATH}\lib -lglew32 - export(LIBS) -} - -defineTest( qt ) { - CONFIG *= uitools - export(CONFIG) - QT += opengl network script sql - export(QT) -} - -defineTest( glut ) { - - ####################################### - ## Enter here the correct path to GLUT - ####################################### - - GLUT_PATH = c:\libs\glut-3.7 - - ######################################## - - !exists ( $${GLUT_PATH} ) { - error (ERROR: GLUT not found or wrong path entry in OpenMesh\qmake\packages\packages.Windows! Please adjust it to your path!) - } - INCLUDEPATH *= $${GLUT_PATH}\include - export(INCLUDEPATH) - LIBS *= -L$${GLUT_PATH}\lib -lglut32 - export(LIBS) -} - -defineTest( openmp ) { - QMAKE_CXXFLAGS_DEBUG += /openmp - QMAKE_CXXFLAGS_RELEASE += /openmp - export(QMAKE_CXXFLAGS_DEBUG) - export(QMAKE_CXXFLAGS_RELEASE) -} - -defineTest( openmesh ) { - DEFINES += _USE_MATH_DEFINES NOMINMAX - - QMAKE_LIBDIR += $${TOPDIR}/lib/ - QMAKE_LIBDIR += $${TOPDIR}/lib/ - - CONFIG( debug, debug|release ){ - LIBS+= -L$${TOPDIR}/lib -lOpenMeshCored - LIBS+= -L$${TOPDIR}/lib -lOpenMeshToolsd - } else { - LIBS+= -L$${TOPDIR}/lib -lOpenMeshCore - LIBS+= -L$${TOPDIR}/lib -lOpenMeshTools - } - - export(DEFINES) - export(QMAKE_LIBDIR) - export(LIBS) -} - diff --git a/qmake/targets.include b/qmake/targets.include deleted file mode 100644 index 57da389c..00000000 --- a/qmake/targets.include +++ /dev/null @@ -1,126 +0,0 @@ -################################################################################ -# Custom targets -################################################################################ - -defineTest( defineTargets ) { - - # internal target ... Use allclean instead! - # cleanDirs target called by subAllclean. - # removes all lib tmp and Builddirectories created by these qmake scripts - !contains( QMAKE_EXTRA_TARGETS , cleanDirs) { - # Remove temp dirs when doing allclean - cleanDirs.target = cleanDirs - cleanDirs.commands = rm -rf tmp - - contains( TEMPLATE, app ) { - cleanDirs.commands += ; rm -rf $${BUILDDIRECTORY} - } - - - contains( TEMPLATE, lib ) { - cleanDirs.commands += ; rm -rf lib - } - - export(cleanDirs.target) - export(cleanDirs.commands) - export(cleanDirs.depends) - export(cleanDirs.CONFIG) - - QMAKE_EXTRA_TARGETS += cleanDirs - export(QMAKE_EXTRA_TARGETS) - } - - # internal target ... Use allclean instead! - # main local subAllclean target called by allclean (see below) - # this one calls - # 1. clean to remove temporary files created - # 2. cleanDirs to remove all tmp and lib directories created by qmake - # 3. distclean to remove the rest - !contains( QMAKE_EXTRA_TARGETS , subAllclean) { - # Remove temp dirs when doing allclean - subAllclean.target = subAllclean - subAllclean.depends = clean cleanDirs distclean - - export(subAllclean.target) - export(subAllclean.depends) - - QMAKE_EXTRA_TARGETS += subAllclean - export(QMAKE_EXTRA_TARGETS) - } - - - # basic allclean target, will cleate a recursive target calling subAllclean in the subdirectories makefiles - !contains( QMAKE_EXTRA_TARGETS , allclean) { - allclean.target = allclean - allclean.CONFIG = recursive - allclean.recurse_target = subAllclean - - export(allclean.target) - export(allclean.CONFIG) - export(allclean.recurse_target) - - QMAKE_EXTRA_TARGETS += allclean - export(QMAKE_EXTRA_TARGETS) - } - - !contains( QMAKE_EXTRA_TARGETS , plugindoc ) { - exists ( Documentation ) { - plugindoc.target = plugindoc - PLUGINNAME = $$getCurrentDir() - PLUGINNAME = $$section( PLUGINNAME, "/" ,-1, -1) - - unix { - plugindoc.commands += rm -rf $${TOPDIR}/OpenFlipper/Docs/User/$$PLUGINNAME ; - plugindoc.commands += mkdir $${TOPDIR}/OpenFlipper/Docs/User/$$PLUGINNAME ; - plugindoc.commands += cp Documentation/*.html $${TOPDIR}/OpenFlipper/Docs/User/$$PLUGINNAME ; - exists ( Documentation/pics ) { - plugindoc.commands += cp -r Documentation/pics $${TOPDIR}/OpenFlipper/Docs/User/$$PLUGINNAME ; - } - } - - win32 { - message(Documentaion copy not supported on windows platform) - #plugindoc.commands += rmdir /s $${TOPDIR}/OpenFlipper/Docs/User/$$PLUGINNAME ; - #plugindoc.commands += mkdir $${TOPDIR}/OpenFlipper/Docs/User/$$PLUGINNAME ; - #plugindoc.commands += xcopy /f Documentation/*.html $${TOPDIR}/OpenFlipper/Docs/User/$$PLUGINNAME ; - #exists ( Documentation/pics ) { - # plugindoc.commands += xcopy /f /s Documentation/pics $${TOPDIR}/OpenFlipper/Docs/User/$$PLUGINNAME ; - #} - } - - export(plugindoc.target) - export(plugindoc.commands) - export(plugindoc.depends) - - QMAKE_EXTRA_TARGETS += plugindoc - export(QMAKE_EXTRA_TARGETS) - } - } - - -} - -# target for libraries -# this target will copy all headers to an include subdirectory -# You have to call this after you defined evertything else for your library. -# Otherwise this target doesnt know about the required headers. - -defineTest( installs ) { - - !contains( INSTALLS , includes ) { - contains( TEMPLATE, lib ) { - - includes.path = include/ - includes.extra = cp -f --parents $${HEADERS} include/ - - export(includes.path) - export(includes.extra) - - INSTALLS *= includes - export(INSTALLS) - } - } -} - - - diff --git a/release.howto b/release.howto index c8e9a160..dae655c7 100644 --- a/release.howto +++ b/release.howto @@ -1,13 +1,13 @@ -1. check files, build on windows,mac,linux with cmake +1. check files, build on windows,mac,linux with cmake (-> Done by CI) 2. check files with release numbers: cmake/FindOpenMesh.cmake Doc/changelog.docu src/OpenMesh/Core/System/config.h README VERSION -3. Tag the current version in the svn (checkout, remove .svn readd as tag) -4. Create HTML-Documentation in OpenMesh/Docu/ (!) -5. Create tar-ball and zip-archive +3. Tag the current version in the git +4. Create HTML-Documentation in OpenMesh/Documentation (!) +5. Create tar-ball and zip-archive ( -> Done by CI) > tar cvzf OpenMesh-.tar.gz OpenMesh-/ > tar cvjf OpenMesh-.tar.bz2 OpenMesh-/ > zip -9 -r OpenMesh-.zip OpenMesh-/ diff --git a/src/OpenMesh/Apps/CMakeLists.txt b/src/OpenMesh/Apps/CMakeLists.txt index b182806f..8c775051 100644 --- a/src/OpenMesh/Apps/CMakeLists.txt +++ b/src/OpenMesh/Apps/CMakeLists.txt @@ -39,29 +39,18 @@ if ( BUILD_APPS ) # find needed packages for gui applications find_package (OpenGL) - find_package (GLUT) - - # try to use QT5 if possible otherwise stick to QT4 - set (FORCE_QT4 OFF CACHE BOOL "Use Qt4 even if Qt5 was found") # For the apps, we need qt and opengl to build them - if (NOT QT5_FOUND AND NOT FORCE_QT4) + if (NOT QT5_FOUND) acg_qt5 () endif() - if (NOT QT5_FOUND AND NOT QT4_FOUND) - find_package (Qt4 COMPONENTS QtCore QtGui ) - - set (QT_USE_QTOPENGL 1) - - include (${QT_USE_FILE}) - endif () if ("${CMAKE_GENERATOR}" MATCHES "MinGW Makefiles") message(WARNING "GUI Apps are not build with mingw. (TODO)") endif() - # check for OpenGL and GLUT as our required dependencies - if ((QT5_FOUND OR QT4_FOUND) AND OPENGL_FOUND AND GLUT_FOUND AND NOT "${CMAKE_GENERATOR}" MATCHES "MinGW Makefiles" ) + # check for OpenGL as our required dependencies + if (( QT5_FOUND ) AND OPENGL_FOUND AND NOT "${CMAKE_GENERATOR}" MATCHES "MinGW Makefiles" ) add_subdirectory (Decimating/DecimaterGui) add_subdirectory (QtViewer) @@ -99,18 +88,14 @@ if ( BUILD_APPS ) else () # QT ,Opengl or glut not found - if (NOT QT4_FOUND AND NOT QT5_FOUND) - message ("QT 4 and 5 not found! Skipping some apps.") + if (NOT QT5_FOUND) + message ("QT5 not found! Skipping some apps.") endif () if (NOT OPENGL_FOUND) message ("OpengGL not found! Skipping some apps.") endif () - if (NOT GLUT_FOUND) - message ("GLUT not found! Skipping some apps.") - endif () - endif () endif() # Project is OpenMesh standalone diff --git a/src/OpenMesh/Apps/Decimating/CmdOption.hh b/src/OpenMesh/Apps/Decimating/CmdOption.hh index 7a0d19b0..0861087d 100644 --- a/src/OpenMesh/Apps/Decimating/CmdOption.hh +++ b/src/OpenMesh/Apps/Decimating/CmdOption.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef CMDOPTION #define CMDOPTION @@ -56,7 +51,7 @@ public: typedef T value_type; - CmdOption(const T& _val) : val_(_val), valid_(true), enabled_(false) { } + explicit CmdOption(const T& _val) : val_(_val), valid_(true), enabled_(false) { } CmdOption() : val_(T()),valid_(false), enabled_(false) { } // has been set and has a value @@ -79,7 +74,7 @@ public: operator T () const { return val_; } // operator const T& () const { return val_; } - operator T* () const { return is_valid() ? &val_ : NULL; } + operator T* () const { return is_valid() ? &val_ : nullptr; } private: diff --git a/src/OpenMesh/Apps/Decimating/DecimaterGui/CMakeLists.txt b/src/OpenMesh/Apps/Decimating/DecimaterGui/CMakeLists.txt index 89d0596a..9e86fba5 100644 --- a/src/OpenMesh/Apps/Decimating/DecimaterGui/CMakeLists.txt +++ b/src/OpenMesh/Apps/Decimating/DecimaterGui/CMakeLists.txt @@ -1,54 +1,35 @@ -include (ACGCommon) - -include_directories ( - ../../../.. - ${CMAKE_CURRENT_SOURCE_DIR} - ${GLUT_INCLUDE_DIR} - ${QT_INCLUDE_DIR} -) - - -set (targetName DecimaterGui) - -# source code directories -set (directories - ../../QtViewer - ../ -) - -# collect all header and source files -acg_append_files (headers "*.hh" ${directories}) - -set (sources - ../../QtViewer/QGLViewerWidget.cc - ../../QtViewer/MeshViewerWidgetT.cc - ../DecimaterViewerWidget.cc - ../decimaterviewer.cc -) - -# remove template cc files from source file list -acg_drop_templates (sources) - -# genereate uic and moc targets -if(QT5_FOUND) - acg_qt5_automoc (moc_targets ${headers}) -else() - acg_qt4_automoc (moc_targets ${headers}) -endif() - -if (WIN32) - acg_add_executable (${targetName} WIN32 ${sources} ${headers} ${moc_targets}) - # link to qtmain library to get WinMain function for a non terminal app - target_link_libraries (${targetName} ${QT_QTMAIN_LIBRARY}) -else () - acg_add_executable (${targetName} ${sources} ${headers} ${moc_targets}) -endif () - -target_link_libraries (${targetName} - OpenMeshCore - OpenMeshTools - ${QT_LIBRARIES} - ${OPENGL_LIBRARIES} - ${GLUT_LIBRARIES} -) - +include (ACGCommon) + +include_directories ( + ../../../.. + ${CMAKE_CURRENT_SOURCE_DIR} +) + +set (headers + ../DecimaterViewerWidget.hh + ../../QtViewer/QGLViewerWidget.hh + ../../QtViewer/MeshViewerWidgetT.hh + ../../QtViewer/MeshViewerWidget.hh + ../../QtViewer/MeshViewerWidgetT_impl.hh +) + +set (sources + ../../QtViewer/QGLViewerWidget.cc + ../../QtViewer/MeshViewerWidget.cc + ../DecimaterViewerWidget.cc + ../decimaterviewer.cc +) + +if (WIN32) + acg_add_executable (DecimaterGui WIN32 ${sources} ${headers}) +else () + acg_add_executable (DecimaterGui ${sources} ${headers} ) +endif () + +target_link_libraries (DecimaterGui + OpenMeshCore + OpenMeshTools + Qt5::OpenGL + ${OPENGL_LIBRARIES} +) + diff --git a/src/OpenMesh/Apps/Decimating/DecimaterGui/DecimaterGui.pro b/src/OpenMesh/Apps/Decimating/DecimaterGui/DecimaterGui.pro deleted file mode 100644 index 68862d4b..00000000 --- a/src/OpenMesh/Apps/Decimating/DecimaterGui/DecimaterGui.pro +++ /dev/null @@ -1,24 +0,0 @@ -################################################################################ -# -################################################################################ - -include( $$TOPDIR/qmake/all.include ) - -Application() - -INCLUDEPATH += ../../.. - -Application() -glew() -glut() -openmesh() - -DIRECTORIES = ../../QtViewer ../ - -# Input -HEADERS += $$getFilesFromDir($$DIRECTORIES,*.hh) -SOURCES += ../../QtViewer/QGLViewerWidget.cc ../../QtViewer/MeshViewerWidgetT.cc ../DecimaterViewerWidget.cc -SOURCES += ../decimaterviewer.cc - - -################################################################################ diff --git a/src/OpenMesh/Apps/Decimating/DecimaterViewerWidget.cc b/src/OpenMesh/Apps/Decimating/DecimaterViewerWidget.cc index 5ec3e623..a6508249 100644 --- a/src/OpenMesh/Apps/Decimating/DecimaterViewerWidget.cc +++ b/src/OpenMesh/Apps/Decimating/DecimaterViewerWidget.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //== INCLUDES ================================================================= diff --git a/src/OpenMesh/Apps/Decimating/DecimaterViewerWidget.hh b/src/OpenMesh/Apps/Decimating/DecimaterViewerWidget.hh index c3caec9a..3311521b 100644 --- a/src/OpenMesh/Apps/Decimating/DecimaterViewerWidget.hh +++ b/src/OpenMesh/Apps/Decimating/DecimaterViewerWidget.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef OPENMESHAPPS_DECIMATERVIEWERWIDGET_HH @@ -96,18 +91,18 @@ struct MyTraits : public DEFAULT_TRAITS }; typedef TRIMESH_KERNEL mesh_t; -typedef MeshViewerWidgetT MeshViewerWidget; +typedef MeshViewerWidgetT MeshViewerWidgetDecimaterBase; //== CLASS DEFINITION ========================================================= -class DecimaterViewerWidget : public MeshViewerWidget +class DecimaterViewerWidget : public MeshViewerWidgetDecimaterBase { Q_OBJECT public: - typedef MeshViewerWidget inherited_t; + typedef MeshViewerWidgetDecimaterBase inherited_t; typedef Decimater::DecimaterT decimater_t; typedef Decimater::ModQuadricT< mesh_t >::Handle mod_quadric_t; @@ -123,8 +118,8 @@ public: /// default constructor - DecimaterViewerWidget(QWidget* _parent=0) - : MeshViewerWidget(_parent), + explicit DecimaterViewerWidget(QWidget* _parent=0) + : MeshViewerWidgetDecimaterBase(_parent), animate_(false), timer_(0), steps_(1) @@ -149,7 +144,7 @@ public: public: // inherited - bool open_mesh(const char* _filename, OpenMesh::IO::Options _opt) + bool open_mesh(const char* _filename, OpenMesh::IO::Options _opt) override { bool rc; @@ -175,7 +170,7 @@ protected slots: protected: - virtual void keyPressEvent(QKeyEvent* _event); + virtual void keyPressEvent(QKeyEvent* _event) override; private: diff --git a/src/OpenMesh/Apps/Decimating/commandlineDecimater/CMakeLists.txt b/src/OpenMesh/Apps/Decimating/commandlineDecimater/CMakeLists.txt index 67642927..2fb5a47d 100644 --- a/src/OpenMesh/Apps/Decimating/commandlineDecimater/CMakeLists.txt +++ b/src/OpenMesh/Apps/Decimating/commandlineDecimater/CMakeLists.txt @@ -5,16 +5,9 @@ include_directories ( ${CMAKE_CURRENT_SOURCE_DIR} ) -set (targetName commandlineDecimater) +acg_add_executable (commandlineDecimater ../decimater.cc) -# collect all header and source files -set (sources - ../decimater.cc -) - -acg_add_executable (${targetName} ${sources}) - -target_link_libraries (${targetName} +target_link_libraries (commandlineDecimater OpenMeshCore OpenMeshTools ) diff --git a/src/OpenMesh/Apps/Decimating/commandlineDecimater/commandlineDecimater.pro b/src/OpenMesh/Apps/Decimating/commandlineDecimater/commandlineDecimater.pro deleted file mode 100644 index bf863090..00000000 --- a/src/OpenMesh/Apps/Decimating/commandlineDecimater/commandlineDecimater.pro +++ /dev/null @@ -1,19 +0,0 @@ -################################################################################ -# -################################################################################ - -include( $$TOPDIR/qmake/all.include ) - -INCLUDEPATH += ../../.. - -Application() -glew() -glut() -openmesh() - -DIRECTORIES = .. - -# Input -SOURCES += ../decimater.cc - -################################################################################ diff --git a/src/OpenMesh/Apps/Decimating/decimater.cc b/src/OpenMesh/Apps/Decimating/decimater.cc index eca0b3e4..313c33f8 100644 --- a/src/OpenMesh/Apps/Decimating/decimater.cc +++ b/src/OpenMesh/Apps/Decimating/decimater.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #if !defined(OM_USE_OSG) # define OM_USE_OSG 0 @@ -221,7 +216,7 @@ decimate(const std::string &_ifname, using namespace std; Mesh mesh; - OpenMesh::IO::Options opt; + OpenMesh::IO::Options readopt; OpenMesh::Utils::Timer timer; // ---------------------------------------- read source mesh @@ -232,7 +227,7 @@ decimate(const std::string &_ifname, if (gverbose) clog << _ifname << endl; - if ( !(rc = OpenMesh::IO::read_mesh(mesh, _ifname, opt)) ) + if ( !(rc = OpenMesh::IO::read_mesh(mesh, _ifname, readopt)) ) { cerr << " ERROR: read failed!" << endl; return rc; @@ -243,7 +238,7 @@ decimate(const std::string &_ifname, { // ---- 0 - For module NormalFlipping one needs face normals - if ( !opt.check( OpenMesh::IO::Options::FaceNormal ) ) + if ( !readopt.check( OpenMesh::IO::Options::FaceNormal ) ) { if ( !mesh.has_face_normals() ) mesh.request_face_normals(); @@ -425,11 +420,11 @@ decimate(const std::string &_ifname, ofname.insert(++pos, n ); } - OpenMesh::IO::Options opt; + OpenMesh::IO::Options writeopt; //opt += OpenMesh::IO::Options::Binary; - if ( !OpenMesh::IO::write_mesh(mesh, ofname, opt ) ) + if ( !OpenMesh::IO::write_mesh(mesh, ofname, writeopt ) ) { std::cerr << " Cannot write decimated mesh to file '" << ofname << "'\n"; @@ -464,7 +459,7 @@ int main(int argc, char* argv[]) { case 'D': opt.decorate_name = true; break; case 'd': gdebug = true; break; - case 'h': usage_and_exit(0); + case 'h': usage_and_exit(0); break; case 'i': ifname = optarg; break; case 'M': opt.parse_argument( optarg ); break; case 'n': opt.n_collapses = float(atof(optarg)); break; diff --git a/src/OpenMesh/Apps/Decimating/decimaterviewer.cc b/src/OpenMesh/Apps/Decimating/decimaterviewer.cc index 4a901c29..5edaf767 100644 --- a/src/OpenMesh/Apps/Decimating/decimaterviewer.cc +++ b/src/OpenMesh/Apps/Decimating/decimaterviewer.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifdef _MSC_VER # pragma warning(disable: 4267 4311) @@ -58,12 +53,6 @@ #include "DecimaterViewerWidget.hh" -#ifdef ARCH_DARWIN -#include -#else -#include -#endif - void usage_and_exit(int xcode); @@ -77,13 +66,9 @@ int main(int argc, char **argv) QApplication::setColorSpec( QApplication::CustomColor ); QApplication app(argc,argv); -#if !defined(__APPLE__) - glutInit(&argc,argv); -#endif - if ( !QGLFormat::hasOpenGL() ) { QString msg = "System has no OpenGL support!"; - QMessageBox::critical( NULL, "OpenGL", msg + argv[1] ); + QMessageBox::critical( nullptr, "OpenGL", msg + argv[1] ); return -1; } @@ -98,6 +83,7 @@ int main(int argc, char **argv) case 's': opt += OpenMesh::IO::Options::Swap; break; case 'h': usage_and_exit(0); + break; default: usage_and_exit(1); } @@ -117,7 +103,7 @@ int main(int argc, char **argv) QString msg = "Cannot read mesh from file:\n '"; msg += argv[optind]; msg += "'"; - QMessageBox::critical( NULL, w.windowTitle(), msg ); + QMessageBox::critical( nullptr, w.windowTitle(), msg ); return 1; } } @@ -132,7 +118,7 @@ int main(int argc, char **argv) msg += "- Mesh file didn't provide texture coordinates\n"; msg += "- Texture file does not exist\n"; msg += "- Texture file is not accessible.\n"; - QMessageBox::warning( NULL, w.windowTitle(), msg ); + QMessageBox::warning( nullptr, w.windowTitle(), msg ); } } diff --git a/src/OpenMesh/Apps/Dualizer/CMakeLists.txt b/src/OpenMesh/Apps/Dualizer/CMakeLists.txt index 861f5fed..59b60ea7 100644 --- a/src/OpenMesh/Apps/Dualizer/CMakeLists.txt +++ b/src/OpenMesh/Apps/Dualizer/CMakeLists.txt @@ -2,18 +2,11 @@ include (ACGCommon) include_directories ( ../../.. - ${CMAKE_CURRENT_SOURCE_DIR} ) -set (targetName Dualizer) +acg_add_executable (Dualizer dualizer.cc) -# collect all header and source files -acg_append_files (headers "*.hh" .) -acg_append_files (sources "*.cc" .) - -acg_add_executable (${targetName} ${headers} ${sources}) - -target_link_libraries (${targetName} +target_link_libraries (Dualizer OpenMeshCore OpenMeshTools ) diff --git a/src/OpenMesh/Apps/Dualizer/dualizer.cc b/src/OpenMesh/Apps/Dualizer/dualizer.cc index 57d87c38..e5fcd642 100644 --- a/src/OpenMesh/Apps/Dualizer/dualizer.cc +++ b/src/OpenMesh/Apps/Dualizer/dualizer.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #include diff --git a/src/OpenMesh/Apps/ProgViewer/CMakeLists.txt b/src/OpenMesh/Apps/ProgViewer/CMakeLists.txt index 092d46cc..b2f5eb90 100644 --- a/src/OpenMesh/Apps/ProgViewer/CMakeLists.txt +++ b/src/OpenMesh/Apps/ProgViewer/CMakeLists.txt @@ -3,62 +3,32 @@ include (ACGCommon) include_directories ( ../../.. ${CMAKE_CURRENT_SOURCE_DIR} - ${GLUT_INCLUDE_DIR} - ${QT_INCLUDE_DIR} ) -set (targetName ProgViewer) +set( headers + ProgViewerWidget.hh + ../QtViewer/QGLViewerWidget.hh + ../QtViewer/MeshViewerWidgetT.hh + ../QtViewer/MeshViewerWidgetT_impl.hh +) -# collect all header and source files -acg_append_files (headers "*.hh" .) -acg_append_files (sources "*.cc" .) - -list (APPEND sources "../QtViewer/QGLViewerWidget.cc") -list (APPEND sources "../QtViewer/MeshViewerWidgetT.cc") - -list (APPEND headers "../QtViewer/QGLViewerWidget.hh") -list (APPEND headers "../QtViewer/MeshViewerWidgetT.hh") - - -# # source code directories -# set (directories -# . -# ../QtViewer -# ) - -# # collect all header and source files -# acg_append_files (headers "*.hh" ${directories}) - -# set (sources -# ../../QtViewer/QGLViewerWidget.cc -# ../../QtViewer/MeshViewerWidgetT.cc -# ./ProgViewerWidget.cc -# ) - -# remove template cc files from source file list -acg_drop_templates (sources) - -# genereate uic and moc targets -if(QT5_FOUND) - acg_qt5_automoc (moc_targets ${headers}) -else() - acg_qt4_automoc (moc_targets ${headers}) -endif() +set( sources + ProgViewerWidget.cc + progviewer.cc + ../QtViewer/QGLViewerWidget.cc +) if (WIN32) - acg_add_executable (${targetName} WIN32 ${sources} ${headers} ${moc_targets}) - # link to qtmain library to get WinMain function for a non terminal app - target_link_libraries (${targetName} ${QT_QTMAIN_LIBRARY}) + acg_add_executable( ProgViewer WIN32 ${sources} ${headers}) else () - acg_add_executable (${targetName} ${sources} ${headers} ${moc_targets}) + acg_add_executable( ProgViewer ${sources} ${headers}) endif () -target_link_libraries (${targetName} +target_link_libraries ( ProgViewer OpenMeshCore OpenMeshTools - ${QT_LIBRARIES} + Qt5::OpenGL ${OPENGL_LIBRARIES} - ${GLUT_LIBRARIES} ) diff --git a/src/OpenMesh/Apps/ProgViewer/OpenMesh_Apps_ProgViewer.vcproj b/src/OpenMesh/Apps/ProgViewer/OpenMesh_Apps_ProgViewer.vcproj deleted file mode 100644 index 0ae89add..00000000 --- a/src/OpenMesh/Apps/ProgViewer/OpenMesh_Apps_ProgViewer.vcproj +++ /dev/null @@ -1,274 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/OpenMesh/Apps/ProgViewer/ProgViewerWidget.cc b/src/OpenMesh/Apps/ProgViewer/ProgViewerWidget.cc index 998bf0b3..7bd4b288 100644 --- a/src/OpenMesh/Apps/ProgViewer/ProgViewerWidget.cc +++ b/src/OpenMesh/Apps/ProgViewer/ProgViewerWidget.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //== INCLUDES ================================================================= diff --git a/src/OpenMesh/Apps/ProgViewer/ProgViewerWidget.hh b/src/OpenMesh/Apps/ProgViewer/ProgViewerWidget.hh index dbb619b1..c62201af 100644 --- a/src/OpenMesh/Apps/ProgViewer/ProgViewerWidget.hh +++ b/src/OpenMesh/Apps/ProgViewer/ProgViewerWidget.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef OPENMESHAPPS_PROGVIEWERWIDGET_HH @@ -68,7 +63,7 @@ using namespace OpenMesh; using namespace OpenMesh::Attributes; -struct MyTraits : public OpenMesh::DefaultTraits +struct ProgTraits : public OpenMesh::DefaultTraits { VertexAttributes ( OpenMesh::Attributes::Normal | OpenMesh::Attributes::Status ); @@ -79,28 +74,32 @@ struct MyTraits : public OpenMesh::DefaultTraits }; -typedef OpenMesh::TriMesh_ArrayKernelT MyMesh; -typedef MeshViewerWidgetT MeshViewerWidget; +typedef OpenMesh::TriMesh_ArrayKernelT MyMesh; +typedef MeshViewerWidgetT MeshViewerWidgetProgBase; //== CLASS DEFINITION ========================================================= -class ProgViewerWidget : public MeshViewerWidget +class ProgViewerWidget : public MeshViewerWidgetProgBase { Q_OBJECT public: - typedef MeshViewerWidget Base; + typedef MeshViewerWidgetProgBase Base; typedef ProgViewerWidget This; public: /// default constructor - ProgViewerWidget(QWidget* _parent=0) - : MeshViewerWidget(_parent) + explicit ProgViewerWidget(QWidget* _parent=0) + : MeshViewerWidgetProgBase(_parent), + n_base_vertices_(0), + n_base_faces_(0), + n_detail_vertices_(0), + n_max_vertices_(0) { timer_ = new QTimer(this); @@ -138,7 +137,7 @@ private: /// coarsen mesh down to _n vertices void coarsen(unsigned int _n); - virtual void keyPressEvent(QKeyEvent* _event); + virtual void keyPressEvent(QKeyEvent* _event) override; // mesh data bool animateRefinement_; diff --git a/src/OpenMesh/Apps/ProgViewer/progviewer.cc b/src/OpenMesh/Apps/ProgViewer/progviewer.cc index fbe31557..6f8eebc5 100644 --- a/src/OpenMesh/Apps/ProgViewer/progviewer.cc +++ b/src/OpenMesh/Apps/ProgViewer/progviewer.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifdef _MSC_VER # pragma warning(disable: 4267 4311) @@ -58,11 +53,6 @@ #include #include -#ifdef ARCH_DARWIN -#include -#else -#include -#endif int main(int argc, char **argv) { @@ -70,8 +60,6 @@ int main(int argc, char **argv) QApplication::setColorSpec( QApplication::CustomColor ); QApplication app(argc,argv); - glutInit(&argc,argv); - if ( !QGLFormat::hasOpenGL() ) { std::cerr << "This system has no OpenGL support.\n"; return -1; diff --git a/src/OpenMesh/Apps/QtViewer/CMakeLists.txt b/src/OpenMesh/Apps/QtViewer/CMakeLists.txt index c3ac4846..231fea48 100644 --- a/src/OpenMesh/Apps/QtViewer/CMakeLists.txt +++ b/src/OpenMesh/Apps/QtViewer/CMakeLists.txt @@ -3,48 +3,34 @@ include (ACGCommon) include_directories ( ../../.. ${CMAKE_CURRENT_SOURCE_DIR} - ${GLUT_INCLUDE_DIR} - ${QT_INCLUDE_DIR} ) -set (targetName QtViewer) - # source code directories set (directories . ) -# collect all header and source files -acg_append_files (headers "*.hh" ${directories}) -acg_append_files (sources "*.cc" ${directories}) -acg_append_files (ui "*.ui" ${directories}) - -# remove template cc files from source file list -acg_drop_templates (sources) - -# genereate uic and moc targets -if(QT5_FOUND) - acg_qt5_autouic (uic_targets ${ui}) - acg_qt5_automoc (moc_targets ${headers}) -else() - acg_qt4_autouic (uic_targets ${ui}) - acg_qt4_automoc (moc_targets ${headers}) -endif() - - -if (WIN32) - acg_add_executable (${targetName} WIN32 ${uic_targets} ${sources} ${headers} ${moc_targets}) - # link to qtmain library to get WinMain function for a non terminal app - target_link_libraries (${targetName} ${QT_QTMAIN_LIBRARY}) -else () - acg_add_executable (${targetName} ${uic_targets} ${sources} ${headers} ${moc_targets}) -endif () - -target_link_libraries (${targetName} - OpenMeshCore - OpenMeshTools - ${QT_LIBRARIES} - ${OPENGL_LIBRARIES} - ${GLUT_LIBRARIES} +set (sources + MeshViewerWidget.cc + QGLViewerWidget.cc + meshviewer.cc +) + +set (headers + MeshViewerWidget.hh + QGLViewerWidget.hh +) + +if (WIN32) + acg_add_executable (QtViewer WIN32 ${sources} ${headers}) +else () + acg_add_executable (QtViewer ${sources} ${headers}) +endif () + +target_link_libraries (QtViewer + OpenMeshCore + OpenMeshTools + Qt5::OpenGL + ${OPENGL_LIBRARIES} ) diff --git a/src/OpenMesh/Apps/QtViewer/MeshViewerWidget.cc b/src/OpenMesh/Apps/QtViewer/MeshViewerWidget.cc new file mode 100644 index 00000000..7385e596 --- /dev/null +++ b/src/OpenMesh/Apps/QtViewer/MeshViewerWidget.cc @@ -0,0 +1,114 @@ +/* ========================================================================= * + * * + * OpenMesh * + * Copyright (c) 2001-2015, RWTH-Aachen University * + * Department of Computer Graphics and Multimedia * + * All rights reserved. * + * www.openmesh.org * + * * + *---------------------------------------------------------------------------* + * This file is part of OpenMesh. * + *---------------------------------------------------------------------------* + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * 1. Redistributions of source code must retain the above copyright notice, * + * this list of conditions and the following disclaimer. * + * * + * 2. Redistributions in binary form must reproduce the above copyright * + * notice, this list of conditions and the following disclaimer in the * + * documentation and/or other materials provided with the distribution. * + * * + * 3. Neither the name of the copyright holder nor the names of its * + * contributors may be used to endorse or promote products derived from * + * this software without specific prior written permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER * + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * + * * + * ========================================================================= */ + + + +#define OPENMESHAPPS_MESHVIEWERWIDGET_CC + +//== INCLUDES ================================================================= + +#include + + +//== IMPLEMENTATION ========================================================== + +/// default constructor +MeshViewerWidget::MeshViewerWidget(QWidget* parent) : MeshViewerWidgetT(parent) +{} + + void MeshViewerWidget::open_mesh_gui(QString fname) +{ + OpenMesh::Utils::Timer t; + t.start(); + if ( fname.isEmpty() || !open_mesh(fname.toLocal8Bit(), _options) ) + { + QString msg = "Cannot read mesh from file:\n '"; + msg += fname; + msg += "'"; + QMessageBox::critical( nullptr, windowTitle(), msg); + } + t.stop(); + std::cout << "Loaded mesh in ~" << t.as_string() << std::endl; + +} + +void MeshViewerWidget::open_texture_gui(QString fname) +{ + if ( fname.isEmpty() || !open_texture( fname.toLocal8Bit() ) ) + { + QString msg = "Cannot load texture image from file:\n '"; + msg += fname; + msg += "'\n\nPossible reasons:\n"; + msg += "- Mesh file didn't provide texture coordinates\n"; + msg += "- Texture file does not exist\n"; + msg += "- Texture file is not accessible.\n"; + QMessageBox::warning( nullptr, windowTitle(), msg ); + } +} + +void MeshViewerWidget::query_open_mesh_file() { + QString fileName = QFileDialog::getOpenFileName(this, + tr("Open mesh file"), + tr(""), + tr("OBJ Files (*.obj);;" + "OFF Files (*.off);;" + "STL Files (*.stl);;" + "All Files (*)")); + if (!fileName.isEmpty()) + open_mesh_gui(fileName); +} + +void MeshViewerWidget::query_open_texture_file() { + QString fileName = QFileDialog::getOpenFileName(this, + tr("Open texture file"), + tr(""), + tr("PNG Files (*.png);;" + "BMP Files (*.bmp);;" + "GIF Files (*.gif);;" + "JPEG Files (*.jpg);;" + "TIFF Files (*.tif);;" + "All Files (*)")); + if (!fileName.isEmpty()) + open_texture_gui(fileName); +} + +//============================================================================= + diff --git a/src/OpenMesh/Apps/QtViewer/MeshViewerWidget.hh b/src/OpenMesh/Apps/QtViewer/MeshViewerWidget.hh index 6addb705..706fc0c9 100644 --- a/src/OpenMesh/Apps/QtViewer/MeshViewerWidget.hh +++ b/src/OpenMesh/Apps/QtViewer/MeshViewerWidget.hh @@ -39,15 +39,9 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ -#ifndef OPENMESHAPPS_VIEWERWIDGET_HH -#define OPENMESHAPPS_VIEWERWIDGET_HH + +#pragma once //== INCLUDES ================================================================= @@ -55,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -66,12 +61,12 @@ using namespace OpenMesh; using namespace OpenMesh::Attributes; -struct MyTraits : public OpenMesh::DefaultTraits +struct MeshViewerWidgetTraits : public OpenMesh::DefaultTraits { HalfedgeAttributes(OpenMesh::Attributes::PrevHalfedge); }; -typedef OpenMesh::TriMesh_ArrayKernelT MyMesh; +typedef OpenMesh::TriMesh_ArrayKernelT MyMesh; @@ -80,70 +75,24 @@ typedef OpenMesh::TriMesh_ArrayKernelT MyMesh; class MeshViewerWidget : public MeshViewerWidgetT { Q_OBJECT + public: /// default constructor - MeshViewerWidget(QWidget* parent=0) : MeshViewerWidgetT(parent) - {} + explicit MeshViewerWidget(QWidget* parent=0); + OpenMesh::IO::Options& options() { return _options; } const OpenMesh::IO::Options& options() const { return _options; } void setOptions(const OpenMesh::IO::Options& opts) { _options = opts; } - void open_mesh_gui(QString fname) - { - OpenMesh::Utils::Timer t; - t.start(); - if ( fname.isEmpty() || !open_mesh(fname.toLocal8Bit(), _options) ) - { - QString msg = "Cannot read mesh from file:\n '"; - msg += fname; - msg += "'"; - QMessageBox::critical( NULL, windowTitle(), msg); - } - t.stop(); - std::cout << "Loaded mesh in ~" << t.as_string() << std::endl; - } - void open_texture_gui(QString fname) - { - if ( fname.isEmpty() || !open_texture( fname.toLocal8Bit() ) ) - { - QString msg = "Cannot load texture image from file:\n '"; - msg += fname; - msg += "'\n\nPossible reasons:\n"; - msg += "- Mesh file didn't provide texture coordinates\n"; - msg += "- Texture file does not exist\n"; - msg += "- Texture file is not accessible.\n"; - QMessageBox::warning( NULL, windowTitle(), msg ); - } - } + void open_mesh_gui(QString fname); + + void open_texture_gui(QString fname); public slots: - void query_open_mesh_file() { - QString fileName = QFileDialog::getOpenFileName(this, - tr("Open mesh file"), - tr(""), - tr("OBJ Files (*.obj);;" - "OFF Files (*.off);;" - "STL Files (*.stl);;" - "All Files (*)")); - if (!fileName.isEmpty()) - open_mesh_gui(fileName); - } - void query_open_texture_file() { - QString fileName = QFileDialog::getOpenFileName(this, - tr("Open texture file"), - tr(""), - tr("PNG Files (*.png);;" - "BMP Files (*.bmp);;" - "GIF Files (*.gif);;" - "JPEG Files (*.jpg);;" - "TIFF Files (*.tif);;" - "All Files (*)")); - if (!fileName.isEmpty()) - open_texture_gui(fileName); - } + void query_open_mesh_file(); + + void query_open_texture_file(); private: OpenMesh::IO::Options _options; }; - -#endif diff --git a/src/OpenMesh/Apps/QtViewer/MeshViewerWidgetT.hh b/src/OpenMesh/Apps/QtViewer/MeshViewerWidgetT.hh index ce076d62..d7223cd7 100644 --- a/src/OpenMesh/Apps/QtViewer/MeshViewerWidgetT.hh +++ b/src/OpenMesh/Apps/QtViewer/MeshViewerWidgetT.hh @@ -39,16 +39,10 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ -#ifndef OPENMESHAPPS_MESHVIEWERWIDGETT_HH -#define OPENMESHAPPS_MESHVIEWERWIDGETT_HH + +#pragma once //== INCLUDES ================================================================= @@ -75,6 +69,7 @@ class QImage; template class MeshViewerWidgetT : public QGLViewerWidget { + public: typedef M Mesh; @@ -82,7 +77,7 @@ public: public: /// default constructor - MeshViewerWidgetT(QWidget* _parent=0) + explicit MeshViewerWidgetT(QWidget* _parent=0) : QGLViewerWidget(_parent), f_strips_(false), tex_id_(0), @@ -90,7 +85,8 @@ public: strips_(mesh_), use_color_(true), show_vnormals_(false), - show_fnormals_(false) + show_fnormals_(false), + normal_scale_(1.0) { add_draw_mode("Points"); add_draw_mode("Hidden-Line"); @@ -121,7 +117,7 @@ public: protected: /// inherited drawing method - virtual void draw_scene(const std::string& _draw_mode); + virtual void draw_scene(const std::string& _draw_mode) override; protected: @@ -175,7 +171,7 @@ protected: // Strip support protected: // inherited - virtual void keyPressEvent( QKeyEvent* _event); + virtual void keyPressEvent( QKeyEvent* _event) override; protected: @@ -195,11 +191,9 @@ protected: //============================================================================= -#if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESHAPPS_MESHVIEWERWIDGET_CC) +#if defined(OM_INCLUDE_TEMPLATES) # define OPENMESH_MESHVIEWERWIDGET_TEMPLATES -# include "MeshViewerWidgetT.cc" +# include "MeshViewerWidgetT_impl.hh" #endif //============================================================================= -#endif // OPENMESHAPPS_MESHVIEWERWIDGETT_HH defined -//============================================================================= diff --git a/src/OpenMesh/Apps/QtViewer/MeshViewerWidgetT.cc b/src/OpenMesh/Apps/QtViewer/MeshViewerWidgetT_impl.hh similarity index 97% rename from src/OpenMesh/Apps/QtViewer/MeshViewerWidgetT.cc rename to src/OpenMesh/Apps/QtViewer/MeshViewerWidgetT_impl.hh index bd814226..e796f7ce 100644 --- a/src/OpenMesh/Apps/QtViewer/MeshViewerWidgetT.cc +++ b/src/OpenMesh/Apps/QtViewer/MeshViewerWidgetT_impl.hh @@ -39,14 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ - -#define OPENMESHAPPS_MESHVIEWERWIDGET_CC +#pragma once //== INCLUDES ================================================================= @@ -74,7 +67,6 @@ using namespace Qt; # undef max #endif -using namespace Qt; //== IMPLEMENTATION ========================================================== @@ -136,7 +128,6 @@ MeshViewerWidgetT::open_mesh(const char* _filename, IO::Options _opt) typename Mesh::ConstVertexIter vIt(mesh_.vertices_begin()); typename Mesh::ConstVertexIter vEnd(mesh_.vertices_end()); - typedef typename Mesh::Point Point; using OpenMesh::Vec3f; Vec3f bbMin, bbMax; @@ -151,7 +142,7 @@ MeshViewerWidgetT::open_mesh(const char* _filename, IO::Options _opt) // set center and radius - set_scene_pos( (bbMin+bbMax)*0.5, (bbMin-bbMax).norm()*0.5 ); + set_scene_pos( (bbMin+bbMax)*0.5f, (bbMin-bbMax).norm()*0.5f ); // for normal display normal_scale_ = (bbMax-bbMin).min()*0.05f; diff --git a/src/OpenMesh/Apps/QtViewer/QGLViewerWidget.cc b/src/OpenMesh/Apps/QtViewer/QGLViewerWidget.cc index 5a589852..ec2ce252 100644 --- a/src/OpenMesh/Apps/QtViewer/QGLViewerWidget.cc +++ b/src/OpenMesh/Apps/QtViewer/QGLViewerWidget.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //== INCLUDES ================================================================= @@ -57,11 +52,7 @@ #include #include // -------------------- -#ifdef ARCH_DARWIN -# include -#else -# include -#endif + // -------------------- #include #include @@ -271,21 +262,21 @@ QGLViewerWidget::draw_scene(const std::string& _draw_mode) if (_draw_mode == "Wireframe") { glDisable(GL_LIGHTING); - glutWireTeapot(0.5); + // glutWireTeapot(0.5); } else if (_draw_mode == "Solid Flat") { glEnable(GL_LIGHTING); glShadeModel(GL_FLAT); - glutSolidTeapot(0.5); + //glutSolidTeapot(0.5); } else if (_draw_mode == "Solid Smooth") { glEnable(GL_LIGHTING); glShadeModel(GL_SMOOTH); - glutSolidTeapot(0.5); + //glutSolidTeapot(0.5); } } @@ -590,8 +581,19 @@ QGLViewerWidget::update_projection_matrix() makeCurrent(); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); - gluPerspective(45.0, (GLfloat) width() / (GLfloat) height(), - 0.01*radius_, 100.0*radius_); + + const double fovY = 45.0; + const double aspect = static_cast(width()) / static_cast(height()); + const double zNear = 0.01*radius_; + const double zFar = 100.0*radius_; + +// Replacement for: gluPerspective(45.0, (GLfloat) width() / (GLfloat) height(), 0.01*radius_, 100.0*radius_); + const double pi = 3.1415926535897932384626433832795; + const double fH = tan( fovY / 360 * pi ) * zNear; + const double fW = fH * aspect; + glFrustum( -fW, fW, -fH, fH, zNear, zFar ); + + glGetDoublev( GL_PROJECTION_MATRIX, projection_matrix_); glMatrixMode( GL_MODELVIEW ); } diff --git a/src/OpenMesh/Apps/QtViewer/QGLViewerWidget.hh b/src/OpenMesh/Apps/QtViewer/QGLViewerWidget.hh index 0f9b06e6..44bf295a 100644 --- a/src/OpenMesh/Apps/QtViewer/QGLViewerWidget.hh +++ b/src/OpenMesh/Apps/QtViewer/QGLViewerWidget.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef OPENMESHAPPS_QGLVIEWERWIDGET_HH @@ -79,7 +74,7 @@ public: typedef QGLWidget Super; // Default constructor. - QGLViewerWidget( QWidget* _parent=0 ); + explicit QGLViewerWidget( QWidget* _parent=0 ); // QGLViewerWidget( QGLFormat& _fmt, QWidget* _parent=0 ); diff --git a/src/OpenMesh/Apps/QtViewer/QtViewer.pro b/src/OpenMesh/Apps/QtViewer/QtViewer.pro deleted file mode 100644 index 42fd4ecc..00000000 --- a/src/OpenMesh/Apps/QtViewer/QtViewer.pro +++ /dev/null @@ -1,19 +0,0 @@ -################################################################################ -# -################################################################################ - -include( $$TOPDIR/qmake/all.include ) - -Application() -glew() -glut() -openmesh() - -DIRECTORIES = . - -# Input -HEADERS += $$getFilesFromDir($$DIRECTORIES,*.hh) -SOURCES += $$getFilesFromDir($$DIRECTORIES,*.cc) -FORMS += $$getFilesFromDir($$DIRECTORIES,*.ui) - -################################################################################ diff --git a/src/OpenMesh/Apps/QtViewer/meshviewer.cc b/src/OpenMesh/Apps/QtViewer/meshviewer.cc index a16d2a03..a3649154 100644 --- a/src/OpenMesh/Apps/QtViewer/meshviewer.cc +++ b/src/OpenMesh/Apps/QtViewer/meshviewer.cc @@ -39,13 +39,6 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ - #ifdef _MSC_VER # pragma warning(disable: 4267 4311) #endif @@ -58,12 +51,6 @@ #include #include -#ifdef ARCH_DARWIN -#include -#else -#include -#endif - #include "MeshViewerWidget.hh" @@ -75,9 +62,6 @@ int main(int argc, char **argv) // OpenGL check QApplication::setColorSpec( QApplication::CustomColor ); QApplication app(argc,argv); -#if !defined(__APPLE__) - glutInit(&argc,argv); -#endif if ( !QGLFormat::hasOpenGL() ) { QString msg = "System has no OpenGL support!"; @@ -95,6 +79,7 @@ int main(int argc, char **argv) case 'b': opt += OpenMesh::IO::Options::Binary; break; case 'h': usage_and_exit(0); + break; case 's': opt += OpenMesh::IO::Options::Swap; break; default: usage_and_exit(1); diff --git a/src/OpenMesh/Apps/Smoothing/CMakeLists.txt b/src/OpenMesh/Apps/Smoothing/CMakeLists.txt index 82eac480..dc397424 100644 --- a/src/OpenMesh/Apps/Smoothing/CMakeLists.txt +++ b/src/OpenMesh/Apps/Smoothing/CMakeLists.txt @@ -5,15 +5,9 @@ include_directories ( ${CMAKE_CURRENT_SOURCE_DIR} ) -set (targetName Smoothing) +acg_add_executable (Smoothing smooth.cc) -# collect all header and source files -acg_append_files (headers "*.hh" .) -acg_append_files (sources "*.cc" .) - -acg_add_executable (${targetName} ${headers} ${sources}) - -target_link_libraries (${targetName} +target_link_libraries (Smoothing OpenMeshCore OpenMeshTools ) diff --git a/src/OpenMesh/Apps/Smoothing/Smoothing.pro b/src/OpenMesh/Apps/Smoothing/Smoothing.pro deleted file mode 100644 index d6400e88..00000000 --- a/src/OpenMesh/Apps/Smoothing/Smoothing.pro +++ /dev/null @@ -1,21 +0,0 @@ -################################################################################ -# -################################################################################ - -include( $$TOPDIR/qmake/all.include ) - -INCLUDEPATH += ../../.. - -Application() -glew() -glut() -openmesh() - -DIRECTORIES = . - -# Input -HEADERS += $$getFilesFromDir($$DIRECTORIES,*.hh) -SOURCES += $$getFilesFromDir($$DIRECTORIES,*.cc) -FORMS += $$getFilesFromDir($$DIRECTORIES,*.ui) - -################################################################################ diff --git a/src/OpenMesh/Apps/Smoothing/smooth.cc b/src/OpenMesh/Apps/Smoothing/smooth.cc index 24c5ef54..76a0e273 100644 --- a/src/OpenMesh/Apps/Smoothing/smooth.cc +++ b/src/OpenMesh/Apps/Smoothing/smooth.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #include @@ -136,7 +131,7 @@ int main(int argc, char **argv) : SmootherT::Normal; break; - case 'h': usage_and_exit(0); + case 'h': usage_and_exit(0); break; case '?': default: usage_and_exit(1); } diff --git a/src/OpenMesh/Apps/Subdivider/MeshViewerWidget.hh b/src/OpenMesh/Apps/Subdivider/MeshViewerWidget.hh index e6a48062..e8e96ca7 100644 --- a/src/OpenMesh/Apps/Subdivider/MeshViewerWidget.hh +++ b/src/OpenMesh/Apps/Subdivider/MeshViewerWidget.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef OPENMESHAPPS_MESHVIEWERWIDGET_HH @@ -71,21 +66,21 @@ typedef OpenMesh::TriMesh_ArrayKernelT Mesh; -class MeshViewerWidget : public MeshViewerWidgetT +class MeshViewerWidgetSubdivider : public MeshViewerWidgetT { public: typedef MeshViewerWidgetT Base; /// default constructor - MeshViewerWidget(QWidget* _parent=0) + explicit MeshViewerWidgetSubdivider(QWidget* _parent=0) : Base(_parent) {} /// destructor - ~MeshViewerWidget() {} + ~MeshViewerWidgetSubdivider() {} /// open mesh - inline bool open_mesh(const char* _filename, OpenMesh::IO::Options _opt) + inline bool open_mesh(const char* _filename, OpenMesh::IO::Options _opt) override { if ( Base::open_mesh( _filename, _opt ) ) { diff --git a/src/OpenMesh/Apps/Subdivider/SubdivideWidget.cc b/src/OpenMesh/Apps/Subdivider/SubdivideWidget.cc index 59d25a12..64a9fcdc 100644 --- a/src/OpenMesh/Apps/Subdivider/SubdivideWidget.cc +++ b/src/OpenMesh/Apps/Subdivider/SubdivideWidget.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= // @@ -92,7 +87,7 @@ using namespace OpenMesh::Subdivider; SubdivideWidget:: SubdivideWidget(QWidget* _parent, const char* _name) : QWidget(_parent), - timer_(NULL), animate_step_(0), max_animate_steps_(4), msecs_(0) + timer_(nullptr), animate_step_(0), max_animate_steps_(4), msecs_(0) { setWindowTitle( QString(_name) ); @@ -103,7 +98,7 @@ SubdivideWidget(QWidget* _parent, const char* _name) // sel_topo_type will be set when adding the radio button.; // examiner widget - viewer_widget_ = new MeshViewerWidget(); + viewer_widget_ = new MeshViewerWidgetSubdivider(); vbox->addWidget(viewer_widget_); diff --git a/src/OpenMesh/Apps/Subdivider/SubdivideWidget.hh b/src/OpenMesh/Apps/Subdivider/SubdivideWidget.hh index 76d6f5fb..2a247596 100644 --- a/src/OpenMesh/Apps/Subdivider/SubdivideWidget.hh +++ b/src/OpenMesh/Apps/Subdivider/SubdivideWidget.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= // @@ -121,7 +116,7 @@ private slots: private: // widgets - MeshViewerWidget* viewer_widget_; + MeshViewerWidgetSubdivider* viewer_widget_; QTimer *timer_; diff --git a/src/OpenMesh/Apps/Subdivider/SubdividerGui/CMakeLists.txt b/src/OpenMesh/Apps/Subdivider/SubdividerGui/CMakeLists.txt index abc8f9f1..85bec8d4 100644 --- a/src/OpenMesh/Apps/Subdivider/SubdividerGui/CMakeLists.txt +++ b/src/OpenMesh/Apps/Subdivider/SubdividerGui/CMakeLists.txt @@ -3,51 +3,32 @@ include (ACGCommon) include_directories ( ../../../.. ${CMAKE_CURRENT_SOURCE_DIR} - ${GLUT_INCLUDE_DIR} - ${QT_INCLUDE_DIR} ) -set (targetName SubdividerGui) - -# source code directories -set (directories - ../../QtViewer - ../ +set (headers + ../MeshViewerWidget.hh + ../SubdivideWidget.hh + ../../QtViewer/QGLViewerWidget.hh + ../../QtViewer/MeshViewerWidgetT.hh + ../../QtViewer/MeshViewerWidgetT_impl.hh ) -# collect all header and source files -acg_append_files (headers "*.hh" ${directories}) - set (sources ../../QtViewer/QGLViewerWidget.cc - ../../QtViewer/MeshViewerWidgetT.cc ../SubdivideWidget.cc ../qtsubdivider.cc ) -# remove template cc files from source file list -acg_drop_templates (sources) - -# genereate uic and moc targets -if(QT5_FOUND) - acg_qt5_automoc (moc_targets ${headers}) -else() - acg_qt4_automoc (moc_targets ${headers}) -endif() - if (WIN32) - acg_add_executable (${targetName} WIN32 ${sources} ${headers} ${moc_targets}) - # link to qtmain library to get WinMain function for a non terminal app - target_link_libraries (${targetName} ${QT_QTMAIN_LIBRARY}) + acg_add_executable (SubdividerGui WIN32 ${sources} ${headers}) else () - acg_add_executable (${targetName} ${sources} ${headers} ${moc_targets}) + acg_add_executable (SubdividerGui ${sources} ${headers}) endif () -target_link_libraries (${targetName} +target_link_libraries (SubdividerGui OpenMeshCore OpenMeshTools - ${QT_LIBRARIES} + Qt5::OpenGL ${OPENGL_LIBRARIES} - ${GLUT_LIBRARIES} ) diff --git a/src/OpenMesh/Apps/Subdivider/SubdividerGui/SubdividerGui.pro b/src/OpenMesh/Apps/Subdivider/SubdividerGui/SubdividerGui.pro deleted file mode 100644 index 27d05e10..00000000 --- a/src/OpenMesh/Apps/Subdivider/SubdividerGui/SubdividerGui.pro +++ /dev/null @@ -1,21 +0,0 @@ -################################################################################ -# -################################################################################ - -include( $$TOPDIR/qmake/all.include ) - -INCLUDEPATH += ../../.. - -Application() -glew() -glut() -openmesh() - -DIRECTORIES = .. ../../QtViewer - -# Input -HEADERS += $$getFilesFromDir($$DIRECTORIES,*.hh) -SOURCES += ../../QtViewer/QGLViewerWidget.cc ../../QtViewer/MeshViewerWidgetT.cc ../SubdivideWidget.cc -SOURCES += ../qtsubdivider.cc - -################################################################################ diff --git a/src/OpenMesh/Apps/Subdivider/adaptive_subdivider.cc b/src/OpenMesh/Apps/Subdivider/adaptive_subdivider.cc index dd155af1..809d5dac 100644 --- a/src/OpenMesh/Apps/Subdivider/adaptive_subdivider.cc +++ b/src/OpenMesh/Apps/Subdivider/adaptive_subdivider.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + // -------------------------------------------------------------- includes ---- @@ -170,7 +165,7 @@ int main(int argc, char **argv) case 'm': { std::stringstream s; s << optarg; s >> max_nv; } break; case 'r': rule_sequence = optarg; break; case 'U': uniform = true; break; - case 'h': usage_and_exit(argv[0],0); + case 'h': usage_and_exit(argv[0],0); break; case '?': default: usage_and_exit(argv[0],1); } diff --git a/src/OpenMesh/Apps/Subdivider/commandlineAdaptiveSubdivider/CMakeLists.txt b/src/OpenMesh/Apps/Subdivider/commandlineAdaptiveSubdivider/CMakeLists.txt index 0cd93599..fab21891 100644 --- a/src/OpenMesh/Apps/Subdivider/commandlineAdaptiveSubdivider/CMakeLists.txt +++ b/src/OpenMesh/Apps/Subdivider/commandlineAdaptiveSubdivider/CMakeLists.txt @@ -5,16 +5,9 @@ include_directories ( ${CMAKE_CURRENT_SOURCE_DIR} ) -set (targetName commandlineAdaptiveSubdivider) +acg_add_executable (commandlineAdaptiveSubdivider ../adaptive_subdivider.cc) -# collect all header and source files -set (sources - ../adaptive_subdivider.cc -) - -acg_add_executable (${targetName} ${sources}) - -target_link_libraries (${targetName} +target_link_libraries (commandlineAdaptiveSubdivider OpenMeshCore OpenMeshTools ) diff --git a/src/OpenMesh/Apps/Subdivider/commandlineAdaptiveSubdivider/commandlineAdaptiveSubdivider.pro b/src/OpenMesh/Apps/Subdivider/commandlineAdaptiveSubdivider/commandlineAdaptiveSubdivider.pro deleted file mode 100644 index 88bae140..00000000 --- a/src/OpenMesh/Apps/Subdivider/commandlineAdaptiveSubdivider/commandlineAdaptiveSubdivider.pro +++ /dev/null @@ -1,15 +0,0 @@ -################################################################################ -# -################################################################################ - -include( $$TOPDIR/qmake/all.include ) - -INCLUDEPATH += ../../.. - -Application() -openmesh() - -# Input -SOURCES += ../adaptive_subdivider.cc - -################################################################################ diff --git a/src/OpenMesh/Apps/Subdivider/commandlineSubdivider/CMakeLists.txt b/src/OpenMesh/Apps/Subdivider/commandlineSubdivider/CMakeLists.txt index bcc48469..7382747e 100644 --- a/src/OpenMesh/Apps/Subdivider/commandlineSubdivider/CMakeLists.txt +++ b/src/OpenMesh/Apps/Subdivider/commandlineSubdivider/CMakeLists.txt @@ -5,16 +5,9 @@ include_directories ( ${CMAKE_CURRENT_SOURCE_DIR} ) -set (targetName commandlineSubdivider) +acg_add_executable (commandlineSubdivider ../subdivider.cc) -# collect all header and source files -set (sources - ../subdivider.cc -) - -acg_add_executable (${targetName} ${sources}) - -target_link_libraries (${targetName} +target_link_libraries (commandlineSubdivider OpenMeshCore OpenMeshTools ) diff --git a/src/OpenMesh/Apps/Subdivider/commandlineSubdivider/commandlineSubdivider.pro b/src/OpenMesh/Apps/Subdivider/commandlineSubdivider/commandlineSubdivider.pro deleted file mode 100644 index f4d941f7..00000000 --- a/src/OpenMesh/Apps/Subdivider/commandlineSubdivider/commandlineSubdivider.pro +++ /dev/null @@ -1,15 +0,0 @@ -################################################################################ -# -################################################################################ - -include( $$TOPDIR/qmake/all.include ) - -INCLUDEPATH += ../../.. - -Application() -openmesh() - -# Input -SOURCES += ../subdivider.cc - -################################################################################ diff --git a/src/OpenMesh/Apps/Subdivider/qtsubdivider.cc b/src/OpenMesh/Apps/Subdivider/qtsubdivider.cc index 85f2a726..665274dc 100644 --- a/src/OpenMesh/Apps/Subdivider/qtsubdivider.cc +++ b/src/OpenMesh/Apps/Subdivider/qtsubdivider.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifdef _MSC_VER # pragma warning(disable: 4267 4311) @@ -57,25 +52,15 @@ #include #include "SubdivideWidget.hh" -#ifdef ARCH_DARWIN -#include -#else -#include -#endif - int main(int argc, char **argv) { // OpenGL check QApplication::setColorSpec( QApplication::CustomColor ); QApplication app(argc,argv); -#if !defined(__APPLE__) - glutInit(&argc,argv); -#endif - if ( !QGLFormat::hasOpenGL() ) { QString msg = "System has no OpenGL support!"; - QMessageBox::critical( NULL, "OpenGL", msg + argv[1], QMessageBox::Ok ); + QMessageBox::critical( nullptr, "OpenGL", msg + argv[1], QMessageBox::Ok ); return -1; } @@ -92,7 +77,7 @@ int main(int argc, char **argv) if ( ! w->open_mesh(argv[1]) ) { QString msg = "Cannot read mesh from file "; - QMessageBox::critical( NULL, argv[1], msg + argv[1], QMessageBox::Ok ); + QMessageBox::critical( nullptr, argv[1], msg + argv[1], QMessageBox::Ok ); return -1; } } diff --git a/src/OpenMesh/Apps/Subdivider/subdivider.cc b/src/OpenMesh/Apps/Subdivider/subdivider.cc index d2b7752e..a4016427 100644 --- a/src/OpenMesh/Apps/Subdivider/subdivider.cc +++ b/src/OpenMesh/Apps/Subdivider/subdivider.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #include #include @@ -234,7 +229,7 @@ int main(int argc, char **argv) } break; } - case 'h': usage_and_exit(0); + case 'h': usage_and_exit(0); break; case '?': default: usage_and_exit(1); } diff --git a/src/OpenMesh/Apps/Unsupported/IvViewer/SoOpenMeshNodeT.hh b/src/OpenMesh/Apps/Unsupported/IvViewer/SoOpenMeshNodeT.hh index 0a88e561..98bdb17a 100644 --- a/src/OpenMesh/Apps/Unsupported/IvViewer/SoOpenMeshNodeT.hh +++ b/src/OpenMesh/Apps/Unsupported/IvViewer/SoOpenMeshNodeT.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= // @@ -128,7 +123,7 @@ private: //============================================================================= #if defined(INCLUDE_TEMPLATES) && !defined(OPENMESH_SOOPENMESHNODE_CC) # define OPENMESH_SOOPENMESHMODE_TEMPLATES -# include "SoOpenMeshNodeT.cc" +# include "SoOpenMeshNodeT_impl.hh" #endif //============================================================================= #endif // OPENMESH_SOOPENMESHNODE_HH diff --git a/src/OpenMesh/Apps/Unsupported/IvViewer/SoOpenMeshNodeT.cc b/src/OpenMesh/Apps/Unsupported/IvViewer/SoOpenMeshNodeT_impl.hh similarity index 96% rename from src/OpenMesh/Apps/Unsupported/IvViewer/SoOpenMeshNodeT.cc rename to src/OpenMesh/Apps/Unsupported/IvViewer/SoOpenMeshNodeT_impl.hh index 348a4f82..e92097ad 100644 --- a/src/OpenMesh/Apps/Unsupported/IvViewer/SoOpenMeshNodeT.cc +++ b/src/OpenMesh/Apps/Unsupported/IvViewer/SoOpenMeshNodeT_impl.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= // diff --git a/src/OpenMesh/Apps/Unsupported/IvViewer/SoOpenMeshSupport.hh b/src/OpenMesh/Apps/Unsupported/IvViewer/SoOpenMeshSupport.hh index 30b7669a..7c38018f 100644 --- a/src/OpenMesh/Apps/Unsupported/IvViewer/SoOpenMeshSupport.hh +++ b/src/OpenMesh/Apps/Unsupported/IvViewer/SoOpenMeshSupport.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef SOOPENMESHSUPPORT_H #define SOOPENMESHSUPPORT_H @@ -83,9 +78,9 @@ PRIVATE_NODE_TYPESYSTEM_SOURCE(_class_); \ SO_NODE_SOURCE_TEMPLATE \ unsigned int _class_::classinstances = 0; \ SO_NODE_SOURCE_TEMPLATE \ -const SoFieldData ** _class_::parentFieldData = NULL; \ +const SoFieldData ** _class_::parentFieldData = nullptr; \ SO_NODE_SOURCE_TEMPLATE \ -SoFieldData * _class_::fieldData = NULL; \ +SoFieldData * _class_::fieldData = nullptr; \ \ SO_NODE_SOURCE_TEMPLATE \ const SoFieldData ** \ diff --git a/src/OpenMesh/Apps/Unsupported/IvViewer/ivviewer.cc b/src/OpenMesh/Apps/Unsupported/IvViewer/ivviewer.cc index d5d80306..74607894 100644 --- a/src/OpenMesh/Apps/Unsupported/IvViewer/ivviewer.cc +++ b/src/OpenMesh/Apps/Unsupported/IvViewer/ivviewer.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #if !defined(USE_SOQT) diff --git a/src/OpenMesh/Apps/Unsupported/OsgViewer/meshviewer.cc b/src/OpenMesh/Apps/Unsupported/OsgViewer/meshviewer.cc index 54aa8b79..bd127bb1 100644 --- a/src/OpenMesh/Apps/Unsupported/OsgViewer/meshviewer.cc +++ b/src/OpenMesh/Apps/Unsupported/OsgViewer/meshviewer.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifdef _MSC_VER # pragma warning(disable: 4267 4311) @@ -83,7 +78,7 @@ int main(int argc, char **argv) if ( !QGLFormat::hasOpenGL() ) { QString msg = "System has no OpenGL support!"; - QMessageBox::critical( NULL, "OpenGL", msg + argv[1], 0 ); + QMessageBox::critical( nullptr, "OpenGL", msg + argv[1], 0 ); return -1; } @@ -120,7 +115,7 @@ int main(int argc, char **argv) QString msg = "Cannot read mesh from file:\n '"; msg += argv[optind]; msg += "'"; - QMessageBox::critical( NULL, w->caption(), msg, 0 ); + QMessageBox::critical( nullptr, w->caption(), msg, 0 ); return 1; } } @@ -135,7 +130,7 @@ int main(int argc, char **argv) msg += "- Mesh file didn't provide texture coordinates\n"; msg += "- Texture file does not exist\n"; msg += "- Texture file is not accessible.\n"; - QMessageBox::warning( NULL, w->caption(), msg, 0 ); + QMessageBox::warning( nullptr, w->caption(), msg, 0 ); } } diff --git a/src/OpenMesh/Apps/Unsupported/OsgViewer/osgviewer.cc b/src/OpenMesh/Apps/Unsupported/OsgViewer/osgviewer.cc index 1d12bb9c..c23e7174 100644 --- a/src/OpenMesh/Apps/Unsupported/OsgViewer/osgviewer.cc +++ b/src/OpenMesh/Apps/Unsupported/OsgViewer/osgviewer.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + // -------------------- STL #include @@ -330,7 +325,7 @@ void mouse(int button, int state, int x, int y) { g.mgr->mouseButtonRelease(button, x, y); // if ( g.mode & FLYMODE ) -// glutIdleFunc(NULL); +// glutIdleFunc(nullptr); } else { diff --git a/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Client/MeshViewerWidgetT.hh b/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Client/MeshViewerWidgetT.hh index 8d1cb246..2ce8bc92 100644 --- a/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Client/MeshViewerWidgetT.hh +++ b/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Client/MeshViewerWidgetT.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef OPENMESHAPPS_MESHVIEWERWIDGETT_HH @@ -173,7 +168,7 @@ protected: //============================================================================= #if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESHAPPS_MESHVIEWERWIDGET_CC) # define OPENMESH_MESHVIEWERWIDGET_TEMPLATES -# include "MeshViewerWidgetT.cc" +# include "MeshViewerWidgetT_impl.hh" #endif //============================================================================= #endif // OPENMESHAPPS_MESHVIEWERWIDGETT_HH defined diff --git a/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Client/MeshViewerWidgetT.cc b/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Client/MeshViewerWidgetT_impl.hh similarity index 97% rename from src/OpenMesh/Apps/Unsupported/Streaming-qt4/Client/MeshViewerWidgetT.cc rename to src/OpenMesh/Apps/Unsupported/Streaming-qt4/Client/MeshViewerWidgetT_impl.hh index f5cf867f..625def94 100644 --- a/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Client/MeshViewerWidgetT.cc +++ b/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Client/MeshViewerWidgetT_impl.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #define OPENMESHAPPS_MESHVIEWERWIDGET_CC diff --git a/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Client/MyMesh.hh b/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Client/MyMesh.hh index 24f5c1df..51cce17d 100644 --- a/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Client/MyMesh.hh +++ b/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Client/MyMesh.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef OPENMESH_APPS_VDPMSTREAMING_CLIENT_MYMESH_HH #define OPENMESH_APPS_VDPMSTREAMING_CLIENT_MYMESH_HH diff --git a/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Client/QGLViewerWidget.cc b/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Client/QGLViewerWidget.cc index ed2e9644..fe4fe2f4 100644 --- a/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Client/QGLViewerWidget.cc +++ b/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Client/QGLViewerWidget.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //== INCLUDES ================================================================= diff --git a/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Client/QGLViewerWidget.hh b/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Client/QGLViewerWidget.hh index f802c27f..1eb3d753 100644 --- a/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Client/QGLViewerWidget.hh +++ b/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Client/QGLViewerWidget.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef OPENMESHAPPS_QGLVIEWERWIDGET_HH diff --git a/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Client/VDPMClientViewerWidget.cc b/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Client/VDPMClientViewerWidget.cc index 7ce0864b..a712f95d 100644 --- a/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Client/VDPMClientViewerWidget.cc +++ b/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Client/VDPMClientViewerWidget.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //== INCLUDES ================================================================= @@ -139,17 +134,15 @@ void VDPMClientViewerWidget::mesh_coloring() vEnd(mesh_.vertices_end()); VHierarchyNodeHandle node_handle; - float ratio; - unsigned char r, g, b; for (; vIt!=vEnd; ++vIt) { node_handle = mesh_.data(*vIt).vhierarchy_node_handle(); - ratio = vhierarchy_.node(node_handle).ratio(); + const float ratio = vhierarchy_.node(node_handle).ratio(); - r = (unsigned char) ((1.0f - ratio) * myYellow[0] + ratio * myBlue[0]); - g = (unsigned char) ((1.0f - ratio) * myYellow[1] + ratio * myBlue[1]); - b = (unsigned char) ((1.0f - ratio) * myYellow[2] + ratio * myBlue[2]); + const unsigned char r = (unsigned char) ((1.0f - ratio) * myYellow[0] + ratio * myBlue[0]); + const unsigned char g = (unsigned char) ((1.0f - ratio) * myYellow[1] + ratio * myBlue[1]); + const unsigned char b = (unsigned char) ((1.0f - ratio) * myYellow[2] + ratio * myBlue[2]); mesh_.set_color(*vIt, OpenMesh::Vec3uc(r,g,b)); } diff --git a/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Client/VDPMClientViewerWidget.hh b/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Client/VDPMClientViewerWidget.hh index 2d6ace46..b309110f 100644 --- a/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Client/VDPMClientViewerWidget.hh +++ b/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Client/VDPMClientViewerWidget.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef OPENMESH_APPS_VDPMSTREAMING_CLIENT_VDPMCLIENTVIEWERWIDGET_HH #define OPENMESH_APPS_VDPMSTREAMING_CLIENT_VDPMCLIENTVIEWERWIDGET_HH diff --git a/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Client/VDPMStreamingClient.cc b/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Client/VDPMStreamingClient.cc index 9e1a6760..77d8c318 100644 --- a/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Client/VDPMStreamingClient.cc +++ b/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Client/VDPMStreamingClient.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + // #ifdef _MSC_VER // # pragma warning(disable: 4267 4311) diff --git a/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Server/ServerSideVDPM.cc b/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Server/ServerSideVDPM.cc index ef7b19b6..17c4c14c 100644 --- a/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Server/ServerSideVDPM.cc +++ b/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Server/ServerSideVDPM.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #include #include diff --git a/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Server/ServerSideVDPM.hh b/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Server/ServerSideVDPM.hh index 7f05ac66..a55025be 100644 --- a/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Server/ServerSideVDPM.hh +++ b/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Server/ServerSideVDPM.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef OPENMESH_APP_SERVERSIDEVDPM_HH #define OPENMESH_APP_SERVERSIDEVDPM_HH @@ -77,7 +72,7 @@ private: public: - ServerSideVDPM() { clear(); } + ServerSideVDPM() :name_(""),tree_id_bits_(0) { clear(); } void clear(); const char* name() const { return name_; } diff --git a/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Server/VDPMServerSession.cc b/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Server/VDPMServerSession.cc index bc093040..b7ad1171 100644 --- a/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Server/VDPMServerSession.cc +++ b/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Server/VDPMServerSession.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #include #include @@ -69,7 +64,7 @@ set_vdpm(const char _vdpm_name[256]) } #endif vdpm_ = ((VDPMServerViewerWidget *) ((VDPMServerSocket *) parent())->parent())->get_vdpm(_vdpm_name); - if (vdpm_ == NULL) + if (vdpm_ == nullptr) return false; vhierarchy_ = &vdpm_->vhierarchy(); diff --git a/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Server/VDPMServerSession.hh b/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Server/VDPMServerSession.hh index b5f95906..bdf6fb51 100644 --- a/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Server/VDPMServerSession.hh +++ b/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Server/VDPMServerSession.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef OPENMESH_APP_VDPMSTREAMING_SERVER_VDPMSERVERSESSION_HH #define OPENMESH_APP_VDPMSTREAMING_SERVER_VDPMSERVERSESSION_HH diff --git a/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Server/VDPMServerSocket.hh b/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Server/VDPMServerSocket.hh index 66ea9495..27f1b4b6 100644 --- a/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Server/VDPMServerSocket.hh +++ b/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Server/VDPMServerSocket.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef OPENMESH_APP_VDPMSTREAMING_SERVER_VDPMSERVERSOCKET_HH #define OPENMESH_APP_VDPMSTREAMING_SERVER_VDPMSERVERSOCKET_HH diff --git a/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Server/VDPMServerViewerWidget.cc b/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Server/VDPMServerViewerWidget.cc index c48a1702..3fdc6011 100644 --- a/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Server/VDPMServerViewerWidget.cc +++ b/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Server/VDPMServerViewerWidget.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #include #include @@ -77,7 +72,7 @@ get_vdpm(const char _vdpm_name[256]) } } - return NULL; + return nullptr; } void diff --git a/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Server/VDPMServerViewerWidget.hh b/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Server/VDPMServerViewerWidget.hh index 05db2243..25fe6ebe 100644 --- a/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Server/VDPMServerViewerWidget.hh +++ b/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Server/VDPMServerViewerWidget.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef OPENMESH_APP_VDPMSTREAMING_SERVER_VDPMSTREAMINGSERVERWIDGET_HH #define OPENMESH_APP_VDPMSTREAMING_SERVER_VDPMSTREAMINGSERVERWIDGET_HH diff --git a/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Server/VDPMStreamingServer.cc b/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Server/VDPMStreamingServer.cc index 70fc51cc..4d245487 100644 --- a/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Server/VDPMStreamingServer.cc +++ b/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Server/VDPMStreamingServer.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #include diff --git a/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Server/VDPMStreamingServer.hh b/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Server/VDPMStreamingServer.hh index dd673509..49e7b4a8 100644 --- a/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Server/VDPMStreamingServer.hh +++ b/src/OpenMesh/Apps/Unsupported/Streaming-qt4/Server/VDPMStreamingServer.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef OPENMESH_APP_VDPMSTREAMINGSERVER_HH #define OPENMESH_APP_VDPMSTREAMINGSERVER_HH diff --git a/src/OpenMesh/Apps/Unsupported/Streaming/Client/MeshViewerWidgetT.hh b/src/OpenMesh/Apps/Unsupported/Streaming/Client/MeshViewerWidgetT.hh index 8d1cb246..2ce8bc92 100644 --- a/src/OpenMesh/Apps/Unsupported/Streaming/Client/MeshViewerWidgetT.hh +++ b/src/OpenMesh/Apps/Unsupported/Streaming/Client/MeshViewerWidgetT.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef OPENMESHAPPS_MESHVIEWERWIDGETT_HH @@ -173,7 +168,7 @@ protected: //============================================================================= #if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESHAPPS_MESHVIEWERWIDGET_CC) # define OPENMESH_MESHVIEWERWIDGET_TEMPLATES -# include "MeshViewerWidgetT.cc" +# include "MeshViewerWidgetT_impl.hh" #endif //============================================================================= #endif // OPENMESHAPPS_MESHVIEWERWIDGETT_HH defined diff --git a/src/OpenMesh/Apps/Unsupported/Streaming/Client/MeshViewerWidgetT.cc b/src/OpenMesh/Apps/Unsupported/Streaming/Client/MeshViewerWidgetT_impl.hh similarity index 97% rename from src/OpenMesh/Apps/Unsupported/Streaming/Client/MeshViewerWidgetT.cc rename to src/OpenMesh/Apps/Unsupported/Streaming/Client/MeshViewerWidgetT_impl.hh index 6a49cecd..e9aca7d9 100644 --- a/src/OpenMesh/Apps/Unsupported/Streaming/Client/MeshViewerWidgetT.cc +++ b/src/OpenMesh/Apps/Unsupported/Streaming/Client/MeshViewerWidgetT_impl.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #define OPENMESHAPPS_MESHVIEWERWIDGET_CC diff --git a/src/OpenMesh/Apps/Unsupported/Streaming/Client/MyMesh.hh b/src/OpenMesh/Apps/Unsupported/Streaming/Client/MyMesh.hh index 24f5c1df..51cce17d 100644 --- a/src/OpenMesh/Apps/Unsupported/Streaming/Client/MyMesh.hh +++ b/src/OpenMesh/Apps/Unsupported/Streaming/Client/MyMesh.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef OPENMESH_APPS_VDPMSTREAMING_CLIENT_MYMESH_HH #define OPENMESH_APPS_VDPMSTREAMING_CLIENT_MYMESH_HH diff --git a/src/OpenMesh/Apps/Unsupported/Streaming/Client/QGLViewerWidget.cc b/src/OpenMesh/Apps/Unsupported/Streaming/Client/QGLViewerWidget.cc index e1f4cc1a..5f06d982 100644 --- a/src/OpenMesh/Apps/Unsupported/Streaming/Client/QGLViewerWidget.cc +++ b/src/OpenMesh/Apps/Unsupported/Streaming/Client/QGLViewerWidget.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //== INCLUDES ================================================================= diff --git a/src/OpenMesh/Apps/Unsupported/Streaming/Client/QGLViewerWidget.hh b/src/OpenMesh/Apps/Unsupported/Streaming/Client/QGLViewerWidget.hh index d0e95150..ecfd95ea 100644 --- a/src/OpenMesh/Apps/Unsupported/Streaming/Client/QGLViewerWidget.hh +++ b/src/OpenMesh/Apps/Unsupported/Streaming/Client/QGLViewerWidget.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef OPENMESHAPPS_QGLVIEWERWIDGET_HH diff --git a/src/OpenMesh/Apps/Unsupported/Streaming/Client/VDPMClientViewerWidget.cc b/src/OpenMesh/Apps/Unsupported/Streaming/Client/VDPMClientViewerWidget.cc index 29439336..0a4c4fec 100644 --- a/src/OpenMesh/Apps/Unsupported/Streaming/Client/VDPMClientViewerWidget.cc +++ b/src/OpenMesh/Apps/Unsupported/Streaming/Client/VDPMClientViewerWidget.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //== INCLUDES ================================================================= @@ -138,17 +133,15 @@ void VDPMClientViewerWidget::mesh_coloring() vEnd(mesh_.vertices_end()); VHierarchyNodeHandle node_handle; - float ratio; - unsigned char r, g, b; for (; vIt!=vEnd; ++vIt) { node_handle = mesh_.data(*vIt).vhierarchy_node_handle(); - ratio = vhierarchy_.node(node_handle).ratio(); + const float ratio = vhierarchy_.node(node_handle).ratio(); - r = (unsigned char) ((1.0f - ratio) * myYellow[0] + ratio * myBlue[0]); - g = (unsigned char) ((1.0f - ratio) * myYellow[1] + ratio * myBlue[1]); - b = (unsigned char) ((1.0f - ratio) * myYellow[2] + ratio * myBlue[2]); + const unsigned char r = (unsigned char) ((1.0f - ratio) * myYellow[0] + ratio * myBlue[0]); + const unsigned char g = (unsigned char) ((1.0f - ratio) * myYellow[1] + ratio * myBlue[1]); + const unsigned char b = (unsigned char) ((1.0f - ratio) * myYellow[2] + ratio * myBlue[2]); mesh_.set_color(*vIt, OpenMesh::Vec3uc(r,g,b)); } diff --git a/src/OpenMesh/Apps/Unsupported/Streaming/Client/VDPMClientViewerWidget.hh b/src/OpenMesh/Apps/Unsupported/Streaming/Client/VDPMClientViewerWidget.hh index a2b3a193..128e634b 100644 --- a/src/OpenMesh/Apps/Unsupported/Streaming/Client/VDPMClientViewerWidget.hh +++ b/src/OpenMesh/Apps/Unsupported/Streaming/Client/VDPMClientViewerWidget.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef OPENMESH_APPS_VDPMSTREAMING_CLIENT_VDPMCLIENTVIEWERWIDGET_HH #define OPENMESH_APPS_VDPMSTREAMING_CLIENT_VDPMCLIENTVIEWERWIDGET_HH diff --git a/src/OpenMesh/Apps/Unsupported/Streaming/Client/VDPMStreamingClient.cc b/src/OpenMesh/Apps/Unsupported/Streaming/Client/VDPMStreamingClient.cc index 1165dc77..5227a1a8 100644 --- a/src/OpenMesh/Apps/Unsupported/Streaming/Client/VDPMStreamingClient.cc +++ b/src/OpenMesh/Apps/Unsupported/Streaming/Client/VDPMStreamingClient.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + // #ifdef _MSC_VER // # pragma warning(disable: 4267 4311) diff --git a/src/OpenMesh/Apps/Unsupported/Streaming/Server/ServerSideVDPM.cc b/src/OpenMesh/Apps/Unsupported/Streaming/Server/ServerSideVDPM.cc index ef7b19b6..17c4c14c 100644 --- a/src/OpenMesh/Apps/Unsupported/Streaming/Server/ServerSideVDPM.cc +++ b/src/OpenMesh/Apps/Unsupported/Streaming/Server/ServerSideVDPM.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #include #include diff --git a/src/OpenMesh/Apps/Unsupported/Streaming/Server/ServerSideVDPM.hh b/src/OpenMesh/Apps/Unsupported/Streaming/Server/ServerSideVDPM.hh index 5f2b66e5..1d44aed2 100644 --- a/src/OpenMesh/Apps/Unsupported/Streaming/Server/ServerSideVDPM.hh +++ b/src/OpenMesh/Apps/Unsupported/Streaming/Server/ServerSideVDPM.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef OPENMESH_APP_SERVERSIDEVDPM_HH #define OPENMESH_APP_SERVERSIDEVDPM_HH @@ -76,7 +71,7 @@ private: public: - ServerSideVDPM() { clear(); } + ServerSideVDPM(): name_(""),tree_id_bits_(0) { clear(); } void clear(); const char* name() const { return name_; } diff --git a/src/OpenMesh/Apps/Unsupported/Streaming/Server/VDPMServerSession.cc b/src/OpenMesh/Apps/Unsupported/Streaming/Server/VDPMServerSession.cc index 4160d8ef..dac0b24a 100644 --- a/src/OpenMesh/Apps/Unsupported/Streaming/Server/VDPMServerSession.cc +++ b/src/OpenMesh/Apps/Unsupported/Streaming/Server/VDPMServerSession.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #include #include @@ -69,7 +64,7 @@ set_vdpm(const char _vdpm_name[256]) } #endif vdpm_ = ((VDPMServerViewerWidget *) ((VDPMServerSocket *) parent())->parent())->get_vdpm(_vdpm_name); - if (vdpm_ == NULL) + if (vdpm_ == nullptr) return false; vhierarchy_ = &vdpm_->vhierarchy(); diff --git a/src/OpenMesh/Apps/Unsupported/Streaming/Server/VDPMServerSession.hh b/src/OpenMesh/Apps/Unsupported/Streaming/Server/VDPMServerSession.hh index a29d98a4..43c7b57a 100644 --- a/src/OpenMesh/Apps/Unsupported/Streaming/Server/VDPMServerSession.hh +++ b/src/OpenMesh/Apps/Unsupported/Streaming/Server/VDPMServerSession.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef OPENMESH_APP_VDPMSTREAMING_SERVER_VDPMSERVERSESSION_HH #define OPENMESH_APP_VDPMSTREAMING_SERVER_VDPMSERVERSESSION_HH diff --git a/src/OpenMesh/Apps/Unsupported/Streaming/Server/VDPMServerSocket.hh b/src/OpenMesh/Apps/Unsupported/Streaming/Server/VDPMServerSocket.hh index 85267a1f..07643389 100644 --- a/src/OpenMesh/Apps/Unsupported/Streaming/Server/VDPMServerSocket.hh +++ b/src/OpenMesh/Apps/Unsupported/Streaming/Server/VDPMServerSocket.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef OPENMESH_APP_VDPMSTREAMING_SERVER_VDPMSERVERSOCKET_HH #define OPENMESH_APP_VDPMSTREAMING_SERVER_VDPMSERVERSOCKET_HH diff --git a/src/OpenMesh/Apps/Unsupported/Streaming/Server/VDPMServerViewerWidget.cc b/src/OpenMesh/Apps/Unsupported/Streaming/Server/VDPMServerViewerWidget.cc index c07ac30b..2d4e0532 100644 --- a/src/OpenMesh/Apps/Unsupported/Streaming/Server/VDPMServerViewerWidget.cc +++ b/src/OpenMesh/Apps/Unsupported/Streaming/Server/VDPMServerViewerWidget.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #include #include @@ -76,7 +71,7 @@ get_vdpm(const char _vdpm_name[256]) } } - return NULL; + return nullptr; } void diff --git a/src/OpenMesh/Apps/Unsupported/Streaming/Server/VDPMServerViewerWidget.hh b/src/OpenMesh/Apps/Unsupported/Streaming/Server/VDPMServerViewerWidget.hh index 0a7b47c1..3fc4c165 100644 --- a/src/OpenMesh/Apps/Unsupported/Streaming/Server/VDPMServerViewerWidget.hh +++ b/src/OpenMesh/Apps/Unsupported/Streaming/Server/VDPMServerViewerWidget.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef OPENMESH_APP_VDPMSTREAMING_SERVER_VDPMSTREAMINGSERVERWIDGET_HH #define OPENMESH_APP_VDPMSTREAMING_SERVER_VDPMSTREAMINGSERVERWIDGET_HH diff --git a/src/OpenMesh/Apps/Unsupported/Streaming/Server/VDPMStreamingServer.cc b/src/OpenMesh/Apps/Unsupported/Streaming/Server/VDPMStreamingServer.cc index 06180f0a..3b99b228 100644 --- a/src/OpenMesh/Apps/Unsupported/Streaming/Server/VDPMStreamingServer.cc +++ b/src/OpenMesh/Apps/Unsupported/Streaming/Server/VDPMStreamingServer.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #include diff --git a/src/OpenMesh/Apps/Unsupported/Streaming/Server/VDPMStreamingServer.hh b/src/OpenMesh/Apps/Unsupported/Streaming/Server/VDPMStreamingServer.hh index dd673509..49e7b4a8 100644 --- a/src/OpenMesh/Apps/Unsupported/Streaming/Server/VDPMStreamingServer.hh +++ b/src/OpenMesh/Apps/Unsupported/Streaming/Server/VDPMStreamingServer.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef OPENMESH_APP_VDPMSTREAMINGSERVER_HH #define OPENMESH_APP_VDPMSTREAMINGSERVER_HH diff --git a/src/OpenMesh/Apps/VDProgMesh/Analyzer/Analyzer.pro b/src/OpenMesh/Apps/VDProgMesh/Analyzer/Analyzer.pro deleted file mode 100644 index b93a0cbb..00000000 --- a/src/OpenMesh/Apps/VDProgMesh/Analyzer/Analyzer.pro +++ /dev/null @@ -1,26 +0,0 @@ -################################################################################ -# -################################################################################ - -include( $$TOPDIR/qmake/all.include ) - -INCLUDEPATH += ../../../.. - -CONFIG += glew glut - -Application() - -LIBS += -Wl,-rpath=$${TOPDIR}/OpenMesh/Core/lib/$${BUILDDIRECTORY} -lCore -LIBS += -Wl,-rpath=$${TOPDIR}/OpenMesh/Tools/lib/$${BUILDDIRECTORY} -lTools -LIBS += -lglut -QMAKE_LIBDIR += $${TOPDIR}/OpenMesh/Core/lib/$${BUILDDIRECTORY} -QMAKE_LIBDIR += $${TOPDIR}/OpenMesh/Tools/lib/$${BUILDDIRECTORY} - -DIRECTORIES = . - -# Input -HEADERS += $$getFilesFromDir($$DIRECTORIES,*.hh) -SOURCES += $$getFilesFromDir($$DIRECTORIES,*.cc) -FORMS += $$getFilesFromDir($$DIRECTORIES,*.ui) - -################################################################################ diff --git a/src/OpenMesh/Apps/VDProgMesh/Analyzer/CMakeLists.txt b/src/OpenMesh/Apps/VDProgMesh/Analyzer/CMakeLists.txt index 16c92eb6..e79f19ab 100644 --- a/src/OpenMesh/Apps/VDProgMesh/Analyzer/CMakeLists.txt +++ b/src/OpenMesh/Apps/VDProgMesh/Analyzer/CMakeLists.txt @@ -5,16 +5,9 @@ include_directories ( ${CMAKE_CURRENT_SOURCE_DIR} ) -set (targetName Analyzer) +acg_add_executable (Analyzer vdpmanalyzer.cc) -# collect all header and source files -set (sources - ./vdpmanalyzer.cc -) - -acg_add_executable (${targetName} ${sources}) - -target_link_libraries (${targetName} +target_link_libraries (Analyzer OpenMeshCore OpenMeshTools ) diff --git a/src/OpenMesh/Apps/VDProgMesh/Analyzer/vdpmanalyzer.cc b/src/OpenMesh/Apps/VDProgMesh/Analyzer/vdpmanalyzer.cc index de55f84d..835cdddb 100644 --- a/src/OpenMesh/Apps/VDProgMesh/Analyzer/vdpmanalyzer.cc +++ b/src/OpenMesh/Apps/VDProgMesh/Analyzer/vdpmanalyzer.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + // -------------------------------------------------------------- includes ---- @@ -276,7 +271,7 @@ int main(int argc, char **argv) { case 'v': verbose = true; break; case 'o': ofname = optarg; break; - case 'h': usage_and_exit(0); + case 'h': usage_and_exit(0); break; default: usage_and_exit(1); } } diff --git a/src/OpenMesh/Apps/VDProgMesh/Synthesizer/CMakeLists.txt b/src/OpenMesh/Apps/VDProgMesh/Synthesizer/CMakeLists.txt index ac1216ed..ec97e48d 100644 --- a/src/OpenMesh/Apps/VDProgMesh/Synthesizer/CMakeLists.txt +++ b/src/OpenMesh/Apps/VDProgMesh/Synthesizer/CMakeLists.txt @@ -3,44 +3,28 @@ include (ACGCommon) include_directories ( ../../../.. ${CMAKE_CURRENT_SOURCE_DIR} - ${GLUT_INCLUDE_DIR} - ${QT_INCLUDE_DIR} ) -set (targetName Synthesizer) +set (headers + VDPMSynthesizerViewerWidget.hh +) -# collect all header and source files -acg_append_files (headers "*.hh" .) -acg_append_files (sources "*.cc" .) +set (sources + ../../QtViewer/QGLViewerWidget.cc + vdpmsynthesizer.cc + VDPMSynthesizerViewerWidget.cc +) -list (APPEND sources "../../QtViewer/QGLViewerWidget.cc") -list (APPEND sources "../../QtViewer/MeshViewerWidgetT.cc") - -list (APPEND headers "../../QtViewer/QGLViewerWidget.hh") -list (APPEND headers "../../QtViewer/MeshViewerWidgetT.hh") - -# remove template cc files from source file list -acg_drop_templates (sources) - -# genereate uic and moc targets -if(QT5_FOUND) - acg_qt5_automoc (moc_targets ${headers}) -else() - acg_qt4_automoc (moc_targets ${headers}) -endif() if (WIN32) - acg_add_executable (${targetName} WIN32 ${sources} ${headers} ${moc_targets}) - # link to qtmain library to get WinMain function for a non terminal app - target_link_libraries (${targetName} ${QT_QTMAIN_LIBRARY}) + acg_add_executable (Synthesizer WIN32 ${sources} ${headers}) else () - acg_add_executable (${targetName} ${sources} ${headers} ${moc_targets}) + acg_add_executable (Synthesizer ${sources} ${headers}) endif () -target_link_libraries (${targetName} +target_link_libraries (Synthesizer OpenMeshCore OpenMeshTools - ${QT_LIBRARIES} + Qt5::OpenGL ${OPENGL_LIBRARIES} - ${GLUT_LIBRARIES} ) diff --git a/src/OpenMesh/Apps/VDProgMesh/Synthesizer/Synthesizer.pro b/src/OpenMesh/Apps/VDProgMesh/Synthesizer/Synthesizer.pro deleted file mode 100644 index dad78ae1..00000000 --- a/src/OpenMesh/Apps/VDProgMesh/Synthesizer/Synthesizer.pro +++ /dev/null @@ -1,27 +0,0 @@ -################################################################################ -# -################################################################################ - -include( $$TOPDIR/qmake/all.include ) - -INCLUDEPATH += ../../../.. - -CONFIG += glew glut - -Application() - -LIBS += -Wl,-rpath=$${TOPDIR}/OpenMesh/Core/lib/$${BUILDDIRECTORY} -lCore -LIBS += -Wl,-rpath=$${TOPDIR}/OpenMesh/Tools/lib/$${BUILDDIRECTORY} -lTools -LIBS += -lglut -QMAKE_LIBDIR += $${TOPDIR}/OpenMesh/Core/lib/$${BUILDDIRECTORY} -QMAKE_LIBDIR += $${TOPDIR}/OpenMesh/Tools/lib/$${BUILDDIRECTORY} - -DIRECTORIES = . ../../QtViewer - -# Input -HEADERS += $$getFilesFromDir($$DIRECTORIES,*.hh) -SOURCES += $$getFilesFromDir($$DIRECTORIES,*.cc) -SOURCES -= ../../QtViewer/meshviewer.cc -FORMS += $$getFilesFromDir($$DIRECTORIES,*.ui) - -################################################################################ diff --git a/src/OpenMesh/Apps/VDProgMesh/Synthesizer/VDPMSynthesizerViewerWidget.cc b/src/OpenMesh/Apps/VDProgMesh/Synthesizer/VDPMSynthesizerViewerWidget.cc index 0bc7ead6..026c7318 100644 --- a/src/OpenMesh/Apps/VDProgMesh/Synthesizer/VDPMSynthesizerViewerWidget.cc +++ b/src/OpenMesh/Apps/VDProgMesh/Synthesizer/VDPMSynthesizerViewerWidget.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= // @@ -67,13 +62,6 @@ #include #include -#ifdef ARCH_DARWIN - #include -#else - #include -#endif - - #include #include #include @@ -90,7 +78,14 @@ namespace OpenMesh { //== IMPLEMENTATION ========================================================== VDPMSynthesizerViewerWidget::VDPMSynthesizerViewerWidget(QWidget* _parent, const char* _name) - : MeshViewerWidget(_parent) + : MeshViewerWidget(_parent), + kappa_square_(0.0), + adaptive_mode_(false), + n_base_vertices_(0), + n_base_edges_(0), + n_base_faces_(0), + n_details_(0) + { adaptive_mode_ = true; } diff --git a/src/OpenMesh/Apps/VDProgMesh/Synthesizer/VDPMSynthesizerViewerWidget.hh b/src/OpenMesh/Apps/VDProgMesh/Synthesizer/VDPMSynthesizerViewerWidget.hh index dee20a84..3b465e1c 100644 --- a/src/OpenMesh/Apps/VDProgMesh/Synthesizer/VDPMSynthesizerViewerWidget.hh +++ b/src/OpenMesh/Apps/VDProgMesh/Synthesizer/VDPMSynthesizerViewerWidget.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= // diff --git a/src/OpenMesh/Apps/VDProgMesh/Synthesizer/vdpmsynthesizer.cc b/src/OpenMesh/Apps/VDProgMesh/Synthesizer/vdpmsynthesizer.cc index 84c8f965..d4c11fcd 100644 --- a/src/OpenMesh/Apps/VDProgMesh/Synthesizer/vdpmsynthesizer.cc +++ b/src/OpenMesh/Apps/VDProgMesh/Synthesizer/vdpmsynthesizer.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifdef _MSC_VER # pragma warning(disable: 4267 4311) @@ -57,21 +52,12 @@ #include "VDPMSynthesizerViewerWidget.hh" -#ifdef ARCH_DARWIN - #include -#else - #include -#endif - int main(int argc, char **argv) { // OpenGL check QApplication::setColorSpec( QApplication::CustomColor ); QApplication app(argc,argv); -#if !defined(__APPLE__) - glutInit(&argc,argv); -#endif if ( !QGLFormat::hasOpenGL() ) { std::cerr << "This system has no OpenGL support.\n"; diff --git a/src/OpenMesh/Apps/VDProgMesh/mkbalancedpm/CMakeLists.txt b/src/OpenMesh/Apps/VDProgMesh/mkbalancedpm/CMakeLists.txt index c0e311e4..edb4ff54 100644 --- a/src/OpenMesh/Apps/VDProgMesh/mkbalancedpm/CMakeLists.txt +++ b/src/OpenMesh/Apps/VDProgMesh/mkbalancedpm/CMakeLists.txt @@ -5,16 +5,9 @@ include_directories ( ${CMAKE_CURRENT_SOURCE_DIR} ) -set (targetName mkbalancedpm) +acg_add_executable (mkbalancedpm mkbalancedpm.cc) -# collect all header and source files -set (sources - ./mkbalancedpm.cc -) - -acg_add_executable (${targetName} ${sources}) - -target_link_libraries (${targetName} +target_link_libraries (mkbalancedpm OpenMeshCore OpenMeshTools ) diff --git a/src/OpenMesh/Apps/VDProgMesh/mkbalancedpm/mkbalancedpm.cc b/src/OpenMesh/Apps/VDProgMesh/mkbalancedpm/mkbalancedpm.cc index 6fa32743..77b7dae6 100644 --- a/src/OpenMesh/Apps/VDProgMesh/mkbalancedpm/mkbalancedpm.cc +++ b/src/OpenMesh/Apps/VDProgMesh/mkbalancedpm/mkbalancedpm.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + // -------------------- STL #include @@ -89,7 +84,7 @@ public: public: /// Constructor - ModBalancerT( D &_dec ) + explicit ModBalancerT( D &_dec ) : BaseModQ( _dec ), max_level_(0), n_roots_(0), n_vertices_(0) { @@ -112,14 +107,14 @@ public: public: // inherited - void initialize(void) + void initialize(void) override { BaseModQ::initialize(); n_vertices_ = BaseModQ::mesh().n_vertices(); n_roots_ = calc_bits_for_roots(n_vertices_); } - virtual float collapse_priority(const CollapseInfo& _ci) + virtual float collapse_priority(const CollapseInfo& _ci) override { level_t newlevel = std::max( BaseModQ::mesh().property( level_, _ci.v0 ), BaseModQ::mesh().property( level_, _ci.v1 ) )+1; @@ -140,7 +135,7 @@ public: // inherited } /// post-process halfedge collapse (accumulate quadrics) - void postprocess_collapse(const CollapseInfo& _ci) + void postprocess_collapse(const CollapseInfo& _ci) override { BaseModQ::postprocess_collapse( _ci ); @@ -259,6 +254,7 @@ int main(int argc, char **argv) case 'I': enable_modIS = true; break; case 'h': usage_and_exit(0); + break; default: usage_and_exit(1); } diff --git a/src/OpenMesh/Apps/VDProgMesh/mkbalancedpm/mkbalancedpm.pro b/src/OpenMesh/Apps/VDProgMesh/mkbalancedpm/mkbalancedpm.pro deleted file mode 100644 index b93a0cbb..00000000 --- a/src/OpenMesh/Apps/VDProgMesh/mkbalancedpm/mkbalancedpm.pro +++ /dev/null @@ -1,26 +0,0 @@ -################################################################################ -# -################################################################################ - -include( $$TOPDIR/qmake/all.include ) - -INCLUDEPATH += ../../../.. - -CONFIG += glew glut - -Application() - -LIBS += -Wl,-rpath=$${TOPDIR}/OpenMesh/Core/lib/$${BUILDDIRECTORY} -lCore -LIBS += -Wl,-rpath=$${TOPDIR}/OpenMesh/Tools/lib/$${BUILDDIRECTORY} -lTools -LIBS += -lglut -QMAKE_LIBDIR += $${TOPDIR}/OpenMesh/Core/lib/$${BUILDDIRECTORY} -QMAKE_LIBDIR += $${TOPDIR}/OpenMesh/Tools/lib/$${BUILDDIRECTORY} - -DIRECTORIES = . - -# Input -HEADERS += $$getFilesFromDir($$DIRECTORIES,*.hh) -SOURCES += $$getFilesFromDir($$DIRECTORIES,*.cc) -FORMS += $$getFilesFromDir($$DIRECTORIES,*.ui) - -################################################################################ diff --git a/src/OpenMesh/Apps/mconvert/CMakeLists.txt b/src/OpenMesh/Apps/mconvert/CMakeLists.txt index dc76a122..0ab863b1 100644 --- a/src/OpenMesh/Apps/mconvert/CMakeLists.txt +++ b/src/OpenMesh/Apps/mconvert/CMakeLists.txt @@ -2,18 +2,11 @@ include (ACGCommon) include_directories ( ../../.. - ${CMAKE_CURRENT_SOURCE_DIR} ) -set (targetName mconvert) +acg_add_executable (mconvert mconvert.cc) -# collect all header and source files -acg_append_files (headers "*.hh" .) -acg_append_files (sources "*.cc" .) - -acg_add_executable (${targetName} ${headers} ${sources}) - -target_link_libraries (${targetName} +target_link_libraries (mconvert OpenMeshCore OpenMeshTools ) diff --git a/src/OpenMesh/Apps/mconvert/VS2008mconvert.vcproj b/src/OpenMesh/Apps/mconvert/VS2008mconvert.vcproj deleted file mode 100644 index 6e1cc762..00000000 --- a/src/OpenMesh/Apps/mconvert/VS2008mconvert.vcproj +++ /dev/null @@ -1,195 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/OpenMesh/Apps/mconvert/mconvert.cc b/src/OpenMesh/Apps/mconvert/mconvert.cc index 953e70b1..5cedd6ce 100644 --- a/src/OpenMesh/Apps/mconvert/mconvert.cc +++ b/src/OpenMesh/Apps/mconvert/mconvert.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #include #include @@ -183,6 +178,7 @@ int main(int argc, char *argv[] ) case 'o': ofname = optarg; break; case 'h': usage_and_exit(0); + break; case '?': default: usage_and_exit(1); diff --git a/src/OpenMesh/Apps/mconvert/mconvert.pro b/src/OpenMesh/Apps/mconvert/mconvert.pro deleted file mode 100644 index 69592799..00000000 --- a/src/OpenMesh/Apps/mconvert/mconvert.pro +++ /dev/null @@ -1,22 +0,0 @@ -################################################################################ -# -################################################################################ - -include( $$TOPDIR/qmake/all.include ) - -Application() - -INCLUDEPATH += ../../.. - -glew() -glut() -openmesh() - -DIRECTORIES = . - -# Input -HEADERS += $$getFilesFromDir($$DIRECTORIES,*.hh) -SOURCES += $$getFilesFromDir($$DIRECTORIES,*.cc) -FORMS += $$getFilesFromDir($$DIRECTORIES,*.ui) - -################################################################################ diff --git a/src/OpenMesh/Core/CMakeLists.txt b/src/OpenMesh/Core/CMakeLists.txt index 83b11eb2..abe7a101 100644 --- a/src/OpenMesh/Core/CMakeLists.txt +++ b/src/OpenMesh/Core/CMakeLists.txt @@ -24,10 +24,6 @@ set (directories acg_append_files (headers "*.hh" ${directories}) acg_append_files (sources "*.cc" ${directories}) -#Drop the template only cc files -acg_drop_templates(sources) - - # Disable Library installation when not building OpenMesh on its own but as part of another project! if ( NOT ${PROJECT_NAME} MATCHES "OpenMesh") set(ACG_NO_LIBRARY_INSTALL true) @@ -81,16 +77,16 @@ endif() # Install Header Files (Apple) if ( NOT ACG_PROJECT_MACOS_BUNDLE AND APPLE ) - FILE(GLOB files_install_Geometry "${CMAKE_CURRENT_SOURCE_DIR}/Geometry/*.hh" "${CMAKE_CURRENT_SOURCE_DIR}/Geometry/*T.cc" ) - FILE(GLOB files_install_IO "${CMAKE_CURRENT_SOURCE_DIR}/IO/*.hh" "${CMAKE_CURRENT_SOURCE_DIR}/IO/*T.cc" "${CMAKE_CURRENT_SOURCE_DIR}/IO/*.inl" ) - FILE(GLOB files_install_IO_importer "${CMAKE_CURRENT_SOURCE_DIR}/IO/importer/*.hh" "${CMAKE_CURRENT_SOURCE_DIR}/IO/importer/*T.cc" ) - FILE(GLOB files_install_IO_exporter "${CMAKE_CURRENT_SOURCE_DIR}/IO/exporter/*.hh" "${CMAKE_CURRENT_SOURCE_DIR}/IO/exporter/*T.cc" ) - FILE(GLOB files_install_IO_reader "${CMAKE_CURRENT_SOURCE_DIR}/IO/reader/*.hh" "${CMAKE_CURRENT_SOURCE_DIR}/IO/reader/*T.cc" ) - FILE(GLOB files_install_IO_writer "${CMAKE_CURRENT_SOURCE_DIR}/IO/writer/*.hh" "${CMAKE_CURRENT_SOURCE_DIR}/IO/writer/*T.cc" ) - FILE(GLOB files_install_Mesh "${CMAKE_CURRENT_SOURCE_DIR}/Mesh/*.hh" "${CMAKE_CURRENT_SOURCE_DIR}/Mesh/*T.cc" ) - FILE(GLOB files_install_Mesh_Gen "${CMAKE_CURRENT_SOURCE_DIR}/Mesh/gen/*.hh" "${CMAKE_CURRENT_SOURCE_DIR}/Mesh/gen/*T.cc" ) - FILE(GLOB files_install_System "${CMAKE_CURRENT_SOURCE_DIR}/System/*.hh" "${CMAKE_CURRENT_SOURCE_DIR}/System/*T.cc" "${CMAKE_CURRENT_SOURCE_DIR}/System/config.h" ) - FILE(GLOB files_install_Utils "${CMAKE_CURRENT_SOURCE_DIR}/Utils/*.hh" "${CMAKE_CURRENT_SOURCE_DIR}/Utils/*T.cc" ) + FILE(GLOB files_install_Geometry "${CMAKE_CURRENT_SOURCE_DIR}/Geometry/*.hh" ) + FILE(GLOB files_install_IO "${CMAKE_CURRENT_SOURCE_DIR}/IO/*.hh" "${CMAKE_CURRENT_SOURCE_DIR}/IO/*.inl" ) + FILE(GLOB files_install_IO_importer "${CMAKE_CURRENT_SOURCE_DIR}/IO/importer/*.hh" ) + FILE(GLOB files_install_IO_exporter "${CMAKE_CURRENT_SOURCE_DIR}/IO/exporter/*.hh" ) + FILE(GLOB files_install_IO_reader "${CMAKE_CURRENT_SOURCE_DIR}/IO/reader/*.hh" ) + FILE(GLOB files_install_IO_writer "${CMAKE_CURRENT_SOURCE_DIR}/IO/writer/*.hh" ) + FILE(GLOB files_install_Mesh "${CMAKE_CURRENT_SOURCE_DIR}/Mesh/*.hh" ) + FILE(GLOB files_install_Mesh_Gen "${CMAKE_CURRENT_SOURCE_DIR}/Mesh/gen/*.hh" ) + FILE(GLOB files_install_System "${CMAKE_CURRENT_SOURCE_DIR}/System/*.hh" "${CMAKE_CURRENT_SOURCE_DIR}/System/config.h" ) + FILE(GLOB files_install_Utils "${CMAKE_CURRENT_SOURCE_DIR}/Utils/*.hh" ) INSTALL(FILES ${files_install_Geometry} DESTINATION include/OpenMesh/Core/Geometry ) INSTALL(FILES ${files_install_IO} DESTINATION include/OpenMesh/Core/IO ) INSTALL(FILES ${files_install_IO_importer} DESTINATION include/OpenMesh/Core/IO/importer ) @@ -118,17 +114,6 @@ install(DIRECTORY . PATTERN "Templates" EXCLUDE PATTERN "Debian*" EXCLUDE) -#install Template cc files (required by headers) -install(DIRECTORY . - DESTINATION include/OpenMesh/Core - FILES_MATCHING - PATTERN "*T.cc" - PATTERN "CVS" EXCLUDE - PATTERN ".svn" EXCLUDE - PATTERN "tmp" EXCLUDE - PATTERN "Templates" EXCLUDE - PATTERN "Debian*" EXCLUDE) - #install the config file install(FILES System/config.h DESTINATION include/OpenMesh/Core/System) @@ -138,14 +123,21 @@ install(DIRECTORY IO/ FILES_MATCHING PATTERN "*.inl" PATTERN "CVS" EXCLUDE - PATTERN ".svn" EXCLUDE - PATTERN "reader" EXCLUDE - PATTERN "writer" EXCLUDE - PATTERN "importer" EXCLUDE - PATTERN "exporter" EXCLUDE - PATTERN "tmp" EXCLUDE - PATTERN "Debian*" EXCLUDE ) - + PATTERN ".svn" EXCLUDE + PATTERN "reader" EXCLUDE + PATTERN "writer" EXCLUDE + PATTERN "importer" EXCLUDE + PATTERN "exporter" EXCLUDE + PATTERN "tmp" EXCLUDE + PATTERN "Debian*" EXCLUDE ) endif () +target_include_directories(OpenMeshCore PUBLIC + $ + $) + +install(TARGETS OpenMeshCore EXPORT OpenMeshConfig + ARCHIVE DESTINATION ${ACG_PROJECT_LIBDIR} + LIBRARY DESTINATION ${ACG_PROJECT_LIBDIR} + RUNTIME DESTINATION ${ACG_PROJECT_BINDIR}) diff --git a/src/OpenMesh/Core/Core.pro b/src/OpenMesh/Core/Core.pro deleted file mode 100644 index e7101ba3..00000000 --- a/src/OpenMesh/Core/Core.pro +++ /dev/null @@ -1,43 +0,0 @@ -################################################################################ -# -################################################################################ - -include( $$TOPDIR/qmake/all.include ) - -Library() - -contains( OPENFLIPPER , OpenFlipper ){ - DESTDIR = $${TOPDIR}/OpenMesh/lib -} else { - DESTDIR = $${TOPDIR}/lib -} - - -DIRECTORIES = . Geometry IO IO/exporter IO/importer IO/reader IO/writer \ - Mesh Mesh/gen System Utils - -INCLUDEPATH += ../.. - -CONFIG( debug, debug|release ){ - TARGET = OpenMeshCored -} else { - TARGET = OpenMeshCore -} - -win32 { - DEFINES += _USE_MATH_DEFINES NOMINMAX - CONFIG += static -} - -macx { - # Set library binary header to the correct path - QMAKE_LFLAGS_SONAME = -install_name$${LITERAL_WHITESPACE}$${DESTDIR}/ - export(QMAKE_LFLAGS_SONAME) -} - -# Input -HEADERS += $$getFilesFromDir($$DIRECTORIES,*.hh) -SOURCES += $$getFilesFromDir($$DIRECTORIES,*.cc) -FORMS += $$getFilesFromDir($$DIRECTORIES,*.ui) - -################################################################################ diff --git a/src/OpenMesh/Core/Geometry/Config.hh b/src/OpenMesh/Core/Geometry/Config.hh index b1f1b082..334bd406 100644 --- a/src/OpenMesh/Core/Geometry/Config.hh +++ b/src/OpenMesh/Core/Geometry/Config.hh @@ -40,12 +40,7 @@ * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= diff --git a/src/OpenMesh/Core/Geometry/EigenVectorT.hh b/src/OpenMesh/Core/Geometry/EigenVectorT.hh new file mode 100644 index 00000000..ce9ffc32 --- /dev/null +++ b/src/OpenMesh/Core/Geometry/EigenVectorT.hh @@ -0,0 +1,104 @@ +/* ========================================================================= * + * * + * OpenMesh * + * Copyright (c) 2001-2015, RWTH-Aachen University * + * Department of Computer Graphics and Multimedia * + * All rights reserved. * + * www.openmesh.org * + * * + *---------------------------------------------------------------------------* + * This file is part of OpenMesh. * + *---------------------------------------------------------------------------* + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * 1. Redistributions of source code must retain the above copyright notice, * + * this list of conditions and the following disclaimer. * + * * + * 2. Redistributions in binary form must reproduce the above copyright * + * notice, this list of conditions and the following disclaimer in the * + * documentation and/or other materials provided with the distribution. * + * * + * 3. Neither the name of the copyright holder nor the names of its * + * contributors may be used to endorse or promote products derived from * + * this software without specific prior written permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER * + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * + * * + * ========================================================================= */ + +/** This file contains all code required to use Eigen3 vectors as Mesh + * vectors + */ +#pragma once + +#include +#include +#include + + +namespace OpenMesh { + template + struct vector_traits> { + static_assert(_Rows != Eigen::Dynamic && _Cols != Eigen::Dynamic, + "Should not use dynamic vectors."); + static_assert(_Rows == 1 || _Cols == 1, "Should not use matrices."); + + using vector_type = Eigen::Matrix<_Scalar, _Rows, _Cols, _Options>; + using value_type = _Scalar; + static const size_t size_ = _Rows * _Cols; + static size_t size() { return size_; } +}; + +} // namespace OpenMesh + +namespace Eigen { + + template + typename Derived::Scalar dot(const MatrixBase &x, + const MatrixBase &y) { + return x.dot(y); + } + + template + typename MatrixBase< Derived >::PlainObject cross(const MatrixBase &x, const MatrixBase &y) { + return x.cross(y); + } + + template + typename Derived::Scalar norm(const MatrixBase &x) { + return x.norm(); + } + + template + typename Derived::Scalar sqrnorm(const MatrixBase &x) { + return x.dot(x); + } + + template + MatrixBase &normalize(MatrixBase &x) { + x /= x.norm(); + return x; + } + + template + MatrixBase &vectorize(MatrixBase &x, + typename Derived::Scalar const &val) { + x.fill(val); + return x; + } + +} // namespace Eigen + diff --git a/src/OpenMesh/Core/Geometry/LoopSchemeMaskT.hh b/src/OpenMesh/Core/Geometry/LoopSchemeMaskT.hh index feca7711..9ae62691 100644 --- a/src/OpenMesh/Core/Geometry/LoopSchemeMaskT.hh +++ b/src/OpenMesh/Core/Geometry/LoopSchemeMaskT.hh @@ -40,12 +40,7 @@ * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef LOOPSCHEMEMASKT_HH #define LOOPSCHEMEMASKT_HH @@ -94,17 +89,17 @@ protected: inline static Scalar compute_limit_weight(uint _valence) { - double proj_weight = compute_proj_weight(_valence); - proj_weight = proj_weight/(proj_weight + _valence);//normalize the proj_weight - double weight = (3.0/8.0)/(1.0 - proj_weight + (3.0/8.0)); + double proj_weight_value = compute_proj_weight(_valence); + proj_weight_value = proj_weight_value/(proj_weight_value + _valence);//normalize the proj_weight + double weight = (3.0/8.0)/(1.0 - proj_weight_value + (3.0/8.0)); return (Scalar)weight; } inline static Scalar compute_step_weight(uint _valence) { - double proj_weight = compute_proj_weight(_valence); - proj_weight = proj_weight/(proj_weight + _valence);//normalize the proj_weight - double weight = proj_weight - (3.0/8.0); + double proj_weight_value = compute_proj_weight(_valence); + proj_weight_value = proj_weight_value/(proj_weight_value + _valence);//normalize the proj_weight + double weight = proj_weight_value - (3.0/8.0); return (Scalar)weight; } diff --git a/src/OpenMesh/Core/Geometry/MathDefs.hh b/src/OpenMesh/Core/Geometry/MathDefs.hh index c61bb7d4..82c16eb4 100644 --- a/src/OpenMesh/Core/Geometry/MathDefs.hh +++ b/src/OpenMesh/Core/Geometry/MathDefs.hh @@ -40,12 +40,7 @@ * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef MATHDEFS_HH #define MATHDEFS_HH diff --git a/src/OpenMesh/Core/Geometry/NormalConeT.hh b/src/OpenMesh/Core/Geometry/NormalConeT.hh index 796bbdd8..0b1cc6a1 100644 --- a/src/OpenMesh/Core/Geometry/NormalConeT.hh +++ b/src/OpenMesh/Core/Geometry/NormalConeT.hh @@ -40,12 +40,7 @@ * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + @@ -65,6 +60,7 @@ #include +#include //== NAMESPACES =============================================================== @@ -82,13 +78,14 @@ namespace OpenMesh { the center normal and the opening angle. **/ -template +template class NormalConeT { public: // typedefs - typedef VectorT Vec3; + typedef typename vector_traits::value_type Scalar; + typedef Vector Vec3; //! default constructor (not initialized) @@ -124,7 +121,7 @@ private: //============================================================================= #if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_NORMALCONE_C) #define OPENMESH_NORMALCONE_TEMPLATES -#include "NormalConeT.cc" +#include "NormalConeT_impl.hh" #endif //============================================================================= #endif // OPENMESH_NORMALCONE_HH defined diff --git a/src/OpenMesh/Core/Geometry/NormalConeT.cc b/src/OpenMesh/Core/Geometry/NormalConeT_impl.hh similarity index 89% rename from src/OpenMesh/Core/Geometry/NormalConeT.cc rename to src/OpenMesh/Core/Geometry/NormalConeT_impl.hh index d5281bf1..ed9ce908 100644 --- a/src/OpenMesh/Core/Geometry/NormalConeT.cc +++ b/src/OpenMesh/Core/Geometry/NormalConeT_impl.hh @@ -40,16 +40,6 @@ * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ - - - - //============================================================================= // // CLASS NormalConeT - IMPLEMENTATION @@ -80,8 +70,8 @@ namespace OpenMesh { //== IMPLEMENTATION ========================================================== -template -NormalConeT:: +template +NormalConeT:: NormalConeT(const Vec3& _center_normal, Scalar _angle) : center_normal_(_center_normal), angle_(_angle) { @@ -91,9 +81,9 @@ NormalConeT(const Vec3& _center_normal, Scalar _angle) //---------------------------------------------------------------------------- -template -Scalar -NormalConeT:: +template +typename NormalConeT::Scalar +NormalConeT:: max_angle(const Vec3& _norm) const { Scalar dotp = (center_normal_ | _norm); @@ -105,9 +95,9 @@ max_angle(const Vec3& _norm) const //---------------------------------------------------------------------------- -template -Scalar -NormalConeT:: +template +typename NormalConeT::Scalar +NormalConeT:: max_angle(const NormalConeT& _cone) const { Scalar dotp = (center_normal_ | _cone.center_normal_); @@ -122,12 +112,12 @@ max_angle(const NormalConeT& _cone) const //---------------------------------------------------------------------------- -template +template void -NormalConeT:: +NormalConeT:: merge(const NormalConeT& _cone) { - Scalar dotp = (center_normal_ | _cone.center_normal_); + Scalar dotp = dot(center_normal_, _cone.center_normal_); if (fabs(dotp) < 0.99999f) { diff --git a/src/OpenMesh/Core/Geometry/Plane3d.hh b/src/OpenMesh/Core/Geometry/Plane3d.hh index 50e9ced5..32e68d00 100644 --- a/src/OpenMesh/Core/Geometry/Plane3d.hh +++ b/src/OpenMesh/Core/Geometry/Plane3d.hh @@ -41,12 +41,7 @@ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= // diff --git a/src/OpenMesh/Core/Geometry/QuadricT.hh b/src/OpenMesh/Core/Geometry/QuadricT.hh index 8d2943ae..1c6c9fa5 100644 --- a/src/OpenMesh/Core/Geometry/QuadricT.hh +++ b/src/OpenMesh/Core/Geometry/QuadricT.hh @@ -41,12 +41,7 @@ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + /** \file Core/Geometry/QuadricT.hh @@ -117,7 +112,7 @@ public: {} template - QuadricT(const _Point& _pt) + explicit QuadricT(const _Point& _pt) { set_distance_to_point(_pt); } diff --git a/src/OpenMesh/Core/Geometry/Vector11T.hh b/src/OpenMesh/Core/Geometry/Vector11T.hh index c9d918ba..44258377 100644 --- a/src/OpenMesh/Core/Geometry/Vector11T.hh +++ b/src/OpenMesh/Core/Geometry/Vector11T.hh @@ -169,6 +169,11 @@ class VectorT { std::copy_n(it, DIM, values_.begin()); } + /// construct from an array + explicit VectorT(container&& _array) { + values_ = _array; + } + /// copy & cast constructor (explicit) template auto operator% (const VectorT &_rhs) const -> typename std::enable_if + auto cross (const VectorT &_rhs) const -> + decltype(*this % _rhs) + { + return *this % _rhs; + } + + /// compute scalar product - /// \see OpenMesh::dot + /// \see OpenMesh::dot and .dot() template auto operator|(const VectorT& _rhs) const -> decltype(*this->data() * *_rhs.data()) { @@ -387,6 +402,15 @@ class VectorT { *begin() * *_rhs.begin()); } + /// compute scalar product + /// \see OpenMesh::dot and .operator| + template + auto dot(const VectorT& _rhs) const -> + decltype(*this | _rhs) + { + return *this | _rhs; + } + //------------------------------------------------------------ euclidean norm /// \name Euclidean norm calculations @@ -718,6 +742,62 @@ noexcept(noexcept(_v1.swap(_v2))) { _v1.swap(_v2); } +/// \relates OpenMesh::VectorT +/// non-member norm +template +Scalar norm(const VectorT& _v) { + return _v.norm(); +} + +/// \relates OpenMesh::VectorT +/// non-member sqrnorm +template +Scalar sqrnorm(const VectorT& _v) { + return _v.sqrnorm(); +} +/// \relates OpenMesh::VectorT +/// non-member vectorize +template +VectorT& vectorize(VectorT& _v, OtherScalar const& _val) { + return _v.vectorize(_val); +} + +/// \relates OpenMesh::VectorT +/// non-member normalize +template +VectorT& normalize(VectorT& _v) { + return _v.normalize(); +} + +/// \relates OpenMesh::VectorT +/// non-member maximize +template +VectorT& maximize(VectorT& _v1, VectorT& _v2) { + return _v1.maximize(_v2); +} + +/// \relates OpenMesh::VectorT +/// non-member minimize +template +VectorT& minimize(VectorT& _v1, VectorT& _v2) { + return _v1.minimize(_v2); +} + +/// \relates OpenMesh::VectorT +/// non-member max +template +VectorT max(const VectorT& _v1, const VectorT& _v2) { + return _v1.max(_v2); +} + +/// \relates OpenMesh::VectorT +/// non-member min +template +VectorT min(const VectorT& _v1, const VectorT& _v2) { + return _v1.min(_v2); +} + + //== TYPEDEFS ================================================================= /** 1-byte signed vector */ diff --git a/src/OpenMesh/Core/Geometry/VectorT.hh b/src/OpenMesh/Core/Geometry/VectorT.hh index d8c8f2b1..87a7e1d0 100644 --- a/src/OpenMesh/Core/Geometry/VectorT.hh +++ b/src/OpenMesh/Core/Geometry/VectorT.hh @@ -40,12 +40,7 @@ * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= @@ -274,6 +269,68 @@ cross(const VectorT& _v1, const VectorT& _v2) { } +/// \relates OpenMesh::VectorT +/// non-member norm +template +Scalar norm(const VectorT& _v) { + return _v.norm(); +} + + +/// \relates OpenMesh::VectorT +/// non-member sqrnorm +template +Scalar sqrnorm(const VectorT& _v) { + return _v.sqrnorm(); +} + + +/// \relates OpenMesh::VectorT +/// non-member vectorize +template +VectorT& vectorize(VectorT& _v, OtherScalar const& _val) { + return _v.vectorize(_val); +} + + +/// \relates OpenMesh::VectorT +/// non-member normalize +template +VectorT& normalize(VectorT& _v) { + return _v.normalize(); +} + + +/// \relates OpenMesh::VectorT +/// non-member maximize +template +VectorT& maximize(VectorT& _v1, VectorT& _v2) { + return _v1.maximize(_v2); +} + + +/// \relates OpenMesh::VectorT +/// non-member minimize +template +VectorT& minimize(VectorT& _v1, VectorT& _v2) { + return _v1.minimize(_v2); +} + + +/// \relates OpenMesh::VectorT +/// non-member max +template +VectorT max(VectorT& _v1, VectorT& _v2) { + return VectorT(_v1).maximize(_v2); +} + + +/// \relates OpenMesh::VectorT +/// non-member min +template +VectorT min(VectorT& _v1, VectorT& _v2) { + return VectorT(_v1).minimize(_v2); +} //== TYPEDEFS ================================================================= diff --git a/src/OpenMesh/Core/Geometry/VectorT_inc.hh b/src/OpenMesh/Core/Geometry/VectorT_inc.hh index 96b6c100..8f5f30ff 100644 --- a/src/OpenMesh/Core/Geometry/VectorT_inc.hh +++ b/src/OpenMesh/Core/Geometry/VectorT_inc.hh @@ -41,12 +41,7 @@ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + // Set template keywords and class names properly when // parsing with doxygen. This only seems to work this way since diff --git a/src/OpenMesh/Core/IO/BinaryHelper.cc b/src/OpenMesh/Core/IO/BinaryHelper.cc index d349e7f5..9bd30939 100644 --- a/src/OpenMesh/Core/IO/BinaryHelper.cc +++ b/src/OpenMesh/Core/IO/BinaryHelper.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= diff --git a/src/OpenMesh/Core/IO/BinaryHelper.hh b/src/OpenMesh/Core/IO/BinaryHelper.hh index 3e36e952..da3bb881 100644 --- a/src/OpenMesh/Core/IO/BinaryHelper.hh +++ b/src/OpenMesh/Core/IO/BinaryHelper.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= diff --git a/src/OpenMesh/Core/IO/IOInstances.hh b/src/OpenMesh/Core/IO/IOInstances.hh index 744b9a81..c40de6d4 100644 --- a/src/OpenMesh/Core/IO/IOInstances.hh +++ b/src/OpenMesh/Core/IO/IOInstances.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= @@ -82,6 +77,7 @@ #include #include #include +#include //=== NAMESPACES ============================================================== @@ -104,6 +100,7 @@ static BaseWriter* OFFWriterInstance = &OFFWriter(); static BaseWriter* STLWriterInstance = &STLWriter(); static BaseWriter* OMWriterInstance = &OMWriter(); static BaseWriter* PLYWriterInstance = &PLYWriter(); +static BaseWriter* VTKWriterInstance = &VTKWriter(); //============================================================================= diff --git a/src/OpenMesh/Core/IO/IOManager.cc b/src/OpenMesh/Core/IO/IOManager.cc index 40f6ec69..8b3a4193 100644 --- a/src/OpenMesh/Core/IO/IOManager.cc +++ b/src/OpenMesh/Core/IO/IOManager.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= @@ -263,7 +258,7 @@ find_writer(const std::string& _format) if ((*it)->can_u_write(filename)) return *it; - return NULL; + return nullptr; } diff --git a/src/OpenMesh/Core/IO/IOManager.hh b/src/OpenMesh/Core/IO/IOManager.hh index 58c157f4..ce958c79 100644 --- a/src/OpenMesh/Core/IO/IOManager.hh +++ b/src/OpenMesh/Core/IO/IOManager.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= // @@ -152,7 +147,7 @@ public: bool write(const std::string& _filename, BaseExporter& _be, Options _opt=Options::Default, - std::streamsize _precision = 6); + std::streamsize _precision = 6); /** Write a mesh to open std::ostream _os. The source data structure is specified by the given BaseExporter. The \c save method consecutively queries all @@ -164,7 +159,7 @@ public: const std::string& _ext, BaseExporter& _be, Options _opt=Options::Default, - std::streamsize _precision = 6); + std::streamsize _precision = 6); /// Returns true if the format is supported by one of the reader modules. diff --git a/src/OpenMesh/Core/IO/MeshIO.hh b/src/OpenMesh/Core/IO/MeshIO.hh index 4a00ab5d..33ee5a79 100644 --- a/src/OpenMesh/Core/IO/MeshIO.hh +++ b/src/OpenMesh/Core/IO/MeshIO.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef OM_MESHIO_HH diff --git a/src/OpenMesh/Core/IO/OFFFormat.hh b/src/OpenMesh/Core/IO/OFFFormat.hh index bd87f56b..31f4388c 100644 --- a/src/OpenMesh/Core/IO/OFFFormat.hh +++ b/src/OpenMesh/Core/IO/OFFFormat.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef OPENMESH_IO_OFFFORMAT_HH diff --git a/src/OpenMesh/Core/IO/OMFormat.cc b/src/OpenMesh/Core/IO/OMFormat.cc index 231dfacd..abebc177 100644 --- a/src/OpenMesh/Core/IO/OMFormat.cc +++ b/src/OpenMesh/Core/IO/OMFormat.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= @@ -113,6 +108,19 @@ namespace OMFormat { return hdr; } +//----------------------------------------------------------------------------- + + + std::string as_string(uint8 version) + { + std::stringstream ss; + ss << major_version(version); + ss << "."; + ss << minor_version(version); + return ss.str(); + } + + //----------------------------------------------------------------------------- const char *as_string(Chunk::Entity e) @@ -127,7 +135,7 @@ namespace OMFormat { default: std::clog << "as_string(Chunk::Entity): Invalid value!"; } - return NULL; + return nullptr; } @@ -145,7 +153,7 @@ namespace OMFormat { case Chunk::Type_Custom: return "Custom"; case Chunk::Type_Topology: return "Topology"; } - return NULL; + return nullptr; } @@ -164,7 +172,7 @@ namespace OMFormat { case Chunk::Dim_7D: return "7D"; case Chunk::Dim_8D: return "8D"; } - return NULL; + return nullptr; } @@ -179,7 +187,7 @@ namespace OMFormat { case Chunk::Integer_32 : return "32"; case Chunk::Integer_64 : return "64"; } - return NULL; + return nullptr; } const char *as_string(Chunk::Float_Size d) @@ -190,7 +198,7 @@ namespace OMFormat { case Chunk::Float_64 : return "64"; case Chunk::Float_128: return "128"; } - return NULL; + return nullptr; } @@ -238,6 +246,9 @@ namespace OMFormat { } + //----------------------------------------------------------------------------- + + } // namespace OMFormat // -------------------------------------------------------------------------- diff --git a/src/OpenMesh/Core/IO/OMFormat.hh b/src/OpenMesh/Core/IO/OMFormat.hh index 9bbcd860..0bc8e3da 100644 --- a/src/OpenMesh/Core/IO/OMFormat.hh +++ b/src/OpenMesh/Core/IO/OMFormat.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef OPENMESH_IO_OMFORMAT_HH @@ -257,7 +252,7 @@ namespace OMFormat { PropertyName( ) { } - PropertyName( const std::string& _name ) { *this = _name; } + explicit PropertyName( const std::string& _name ) { *this = _name; } bool is_valid() const { return is_valid( size() ); } @@ -294,7 +289,7 @@ namespace OMFormat { inline size_t chunk_header_size( void ) { return sizeof(uint16); } - /// Return the size of a scale in bytes. + /// Return the size of a scaler in bytes. inline size_t scalar_size( const Chunk::Header& _hdr ) { return _hdr.float_ ? (0x01 << _hdr.bits_) : (0x04 << _hdr.bits_); @@ -355,6 +350,16 @@ namespace OMFormat { #endif } + template bool is_double(const T&) + { + return false; + } + + template <> inline bool is_double(const double&) + { + return true; + } + template bool is_integer(const T) { #if defined(OM_MISSING_HEADER_LIMITS) @@ -469,6 +474,8 @@ namespace OMFormat { // ---------------------------------------- convenience functions + std::string as_string(uint8 version); + const char *as_string(Chunk::Type t); const char *as_string(Chunk::Entity e); const char *as_string(Chunk::Dim d); @@ -744,7 +751,7 @@ namespace OMFormat { //============================================================================= #if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_IO_OMFORMAT_CC) # define OPENMESH_IO_OMFORMAT_TEMPLATES -# include "OMFormatT.cc" +# include "OMFormatT_impl.hh" #endif //============================================================================= #endif diff --git a/src/OpenMesh/Core/IO/OMFormatT.cc b/src/OpenMesh/Core/IO/OMFormatT_impl.hh similarity index 94% rename from src/OpenMesh/Core/IO/OMFormatT.cc rename to src/OpenMesh/Core/IO/OMFormatT_impl.hh index fa332b12..b79333bf 100644 --- a/src/OpenMesh/Core/IO/OMFormatT.cc +++ b/src/OpenMesh/Core/IO/OMFormatT_impl.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= diff --git a/src/OpenMesh/Core/IO/Options.hh b/src/OpenMesh/Core/IO/Options.hh index f2667258..2e642180 100644 --- a/src/OpenMesh/Core/IO/Options.hh +++ b/src/OpenMesh/Core/IO/Options.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef OPENMESH_IO_OPTIONS_HH @@ -115,7 +110,8 @@ public: FaceTexCoord = 0x0400, ///< Has (r) / store (w) face texture coordinates ColorAlpha = 0x0800, ///< Has (r) / store (w) alpha values for colors ColorFloat = 0x1000, ///< Has (r) / store (w) float values for colors (currently only implemented for PLY and OFF files) - Custom = 0x2000 ///< Has (r) custom properties (currently only implemented in PLY Reader ASCII version) + Custom = 0x2000, ///< Has (r) custom properties (currently only implemented in PLY Reader ASCII version) + Status = 0x4000 ///< Has (r) / store (w) status properties }; public: @@ -206,10 +202,14 @@ public: bool vertex_has_normal() const { return check(VertexNormal); } bool vertex_has_color() const { return check(VertexColor); } bool vertex_has_texcoord() const { return check(VertexTexCoord); } + bool vertex_has_status() const { return check(Status); } bool edge_has_color() const { return check(EdgeColor); } + bool edge_has_status() const { return check(Status); } + bool halfedge_has_status() const { return check(Status); } bool face_has_normal() const { return check(FaceNormal); } bool face_has_color() const { return check(FaceColor); } bool face_has_texcoord() const { return check(FaceTexCoord); } + bool face_has_status() const { return check(Status); } bool color_has_alpha() const { return check(ColorAlpha); } bool color_is_float() const { return check(ColorFloat); } diff --git a/src/OpenMesh/Core/IO/SR_binary.hh b/src/OpenMesh/Core/IO/SR_binary.hh index 05c9de8f..dd4f4218 100644 --- a/src/OpenMesh/Core/IO/SR_binary.hh +++ b/src/OpenMesh/Core/IO/SR_binary.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= diff --git a/src/OpenMesh/Core/IO/SR_binary_spec.hh b/src/OpenMesh/Core/IO/SR_binary_spec.hh index 956b6e8f..c9f37b72 100644 --- a/src/OpenMesh/Core/IO/SR_binary_spec.hh +++ b/src/OpenMesh/Core/IO/SR_binary_spec.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= diff --git a/src/OpenMesh/Core/IO/SR_rbo.hh b/src/OpenMesh/Core/IO/SR_rbo.hh index 64275c46..876307ed 100644 --- a/src/OpenMesh/Core/IO/SR_rbo.hh +++ b/src/OpenMesh/Core/IO/SR_rbo.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= diff --git a/src/OpenMesh/Core/IO/SR_store.hh b/src/OpenMesh/Core/IO/SR_store.hh index e1b99a06..07df4782 100644 --- a/src/OpenMesh/Core/IO/SR_store.hh +++ b/src/OpenMesh/Core/IO/SR_store.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= diff --git a/src/OpenMesh/Core/IO/SR_types.hh b/src/OpenMesh/Core/IO/SR_types.hh index 9628f59e..65107674 100644 --- a/src/OpenMesh/Core/IO/SR_types.hh +++ b/src/OpenMesh/Core/IO/SR_types.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= diff --git a/src/OpenMesh/Core/IO/StoreRestore.hh b/src/OpenMesh/Core/IO/StoreRestore.hh index fff6708f..e3966c88 100644 --- a/src/OpenMesh/Core/IO/StoreRestore.hh +++ b/src/OpenMesh/Core/IO/StoreRestore.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= diff --git a/src/OpenMesh/Core/IO/exporter/BaseExporter.hh b/src/OpenMesh/Core/IO/exporter/BaseExporter.hh index 477d95a1..c60181ff 100644 --- a/src/OpenMesh/Core/IO/exporter/BaseExporter.hh +++ b/src/OpenMesh/Core/IO/exporter/BaseExporter.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= @@ -95,21 +90,27 @@ public: // get vertex data virtual Vec3f point(VertexHandle _vh) const = 0; + virtual Vec3d pointd(VertexHandle _vh) const = 0; + virtual bool is_point_double() const = 0; virtual Vec3f normal(VertexHandle _vh) const = 0; + virtual Vec3d normald(VertexHandle _vh) const = 0; + virtual bool is_normal_double() const = 0; virtual Vec3uc color(VertexHandle _vh) const = 0; virtual Vec4uc colorA(VertexHandle _vh) const = 0; - virtual Vec3ui colori(VertexHandle _vh) const = 0; - virtual Vec4ui colorAi(VertexHandle _vh) const = 0; + virtual Vec3ui colori(VertexHandle _vh) const = 0; + virtual Vec4ui colorAi(VertexHandle _vh) const = 0; virtual Vec3f colorf(VertexHandle _vh) const = 0; virtual Vec4f colorAf(VertexHandle _vh) const = 0; virtual Vec2f texcoord(VertexHandle _vh) const = 0; virtual Vec2f texcoord(HalfedgeHandle _heh) const = 0; + virtual OpenMesh::Attributes::StatusInfo status(VertexHandle _vh) const = 0; // get face data virtual unsigned int get_vhandles(FaceHandle _fh, std::vector& _vhandles) const=0; + /// /// \brief getHeh returns the HalfEdgeHandle that belongs to the face /// specified by _fh and has a toVertexHandle that corresponds to _vh. @@ -121,12 +122,14 @@ public: virtual unsigned int get_face_texcoords(std::vector& _hehandles) const = 0; virtual Vec3f normal(FaceHandle _fh) const = 0; + virtual Vec3d normald(FaceHandle _fh) const = 0; virtual Vec3uc color (FaceHandle _fh) const = 0; virtual Vec4uc colorA(FaceHandle _fh) const = 0; virtual Vec3ui colori(FaceHandle _fh) const = 0; virtual Vec4ui colorAi(FaceHandle _fh) const = 0; virtual Vec3f colorf(FaceHandle _fh) const = 0; virtual Vec4f colorAf(FaceHandle _fh) const = 0; + virtual OpenMesh::Attributes::StatusInfo status(FaceHandle _fh) const = 0; // get edge data virtual Vec3uc color(EdgeHandle _eh) const = 0; @@ -135,9 +138,18 @@ public: virtual Vec4ui colorAi(EdgeHandle _eh) const = 0; virtual Vec3f colorf(EdgeHandle _eh) const = 0; virtual Vec4f colorAf(EdgeHandle _eh) const = 0; + virtual OpenMesh::Attributes::StatusInfo status(EdgeHandle _eh) const = 0; + + // get halfedge data + virtual int get_halfedge_id(VertexHandle _vh) = 0; + virtual int get_halfedge_id(FaceHandle _vh) = 0; + virtual int get_next_halfedge_id(HalfedgeHandle _heh) = 0; + virtual int get_to_vertex_id(HalfedgeHandle _heh) = 0; + virtual int get_face_id(HalfedgeHandle _heh) = 0; + virtual OpenMesh::Attributes::StatusInfo status(HalfedgeHandle _heh) const = 0; // get reference to base kernel - virtual const BaseKernel* kernel() { return 0; } + virtual const BaseKernel* kernel() { return nullptr; } // query number of faces, vertices, normals, texcoords @@ -150,10 +162,14 @@ public: virtual bool is_triangle_mesh() const { return false; } virtual bool has_vertex_normals() const { return false; } virtual bool has_vertex_colors() const { return false; } + virtual bool has_vertex_status() const { return false; } virtual bool has_vertex_texcoords() const { return false; } virtual bool has_edge_colors() const { return false; } + virtual bool has_edge_status() const { return false; } + virtual bool has_halfedge_status() const { return false; } virtual bool has_face_normals() const { return false; } virtual bool has_face_colors() const { return false; } + virtual bool has_face_status() const { return false; } }; diff --git a/src/OpenMesh/Core/IO/exporter/ExporterT.hh b/src/OpenMesh/Core/IO/exporter/ExporterT.hh index 9a9d9b3f..8f9dde90 100644 --- a/src/OpenMesh/Core/IO/exporter/ExporterT.hh +++ b/src/OpenMesh/Core/IO/exporter/ExporterT.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= @@ -70,6 +65,7 @@ #include #include #include +#include //=== NAMESPACES ============================================================== @@ -89,66 +85,88 @@ class ExporterT : public BaseExporter public: // Constructor - ExporterT(const Mesh& _mesh) : mesh_(_mesh) {} + explicit ExporterT(const Mesh& _mesh) : mesh_(_mesh) {} // get vertex data - Vec3f point(VertexHandle _vh) const + Vec3f point(VertexHandle _vh) const override { return vector_cast(mesh_.point(_vh)); } - Vec3f normal(VertexHandle _vh) const + Vec3d pointd(VertexHandle _vh) const override { - return (mesh_.has_vertex_normals() - ? vector_cast(mesh_.normal(_vh)) - : Vec3f(0.0f, 0.0f, 0.0f)); + return vector_cast(mesh_.point(_vh)); } - Vec3uc color(VertexHandle _vh) const + bool is_point_double() const override + { + return OMFormat::is_double(typename Mesh::Point()[0]); + } + + bool is_normal_double() const override + { + return OMFormat::is_double(typename Mesh::Normal()[0]); + } + + Vec3f normal(VertexHandle _vh) const override + { + return (mesh_.has_vertex_normals() + ? vector_cast(mesh_.normal(_vh)) + : Vec3f(0.0f, 0.0f, 0.0f)); + } + + Vec3d normald(VertexHandle _vh) const override + { + return (mesh_.has_vertex_normals() + ? vector_cast(mesh_.normal(_vh)) + : Vec3d(0.0f, 0.0f, 0.0f)); + } + + Vec3uc color(VertexHandle _vh) const override { return (mesh_.has_vertex_colors() ? color_cast(mesh_.color(_vh)) : Vec3uc(0, 0, 0)); } - Vec4uc colorA(VertexHandle _vh) const + Vec4uc colorA(VertexHandle _vh) const override { return (mesh_.has_vertex_colors() ? color_cast(mesh_.color(_vh)) : Vec4uc(0, 0, 0, 0)); } - Vec3ui colori(VertexHandle _vh) const + Vec3ui colori(VertexHandle _vh) const override { return (mesh_.has_vertex_colors() ? color_cast(mesh_.color(_vh)) : Vec3ui(0, 0, 0)); } - Vec4ui colorAi(VertexHandle _vh) const + Vec4ui colorAi(VertexHandle _vh) const override { return (mesh_.has_vertex_colors() ? color_cast(mesh_.color(_vh)) : Vec4ui(0, 0, 0, 0)); } - Vec3f colorf(VertexHandle _vh) const + Vec3f colorf(VertexHandle _vh) const override { return (mesh_.has_vertex_colors() ? color_cast(mesh_.color(_vh)) : Vec3f(0, 0, 0)); } - Vec4f colorAf(VertexHandle _vh) const + Vec4f colorAf(VertexHandle _vh) const override { return (mesh_.has_vertex_colors() ? color_cast(mesh_.color(_vh)) : Vec4f(0, 0, 0, 0)); } - Vec2f texcoord(VertexHandle _vh) const + Vec2f texcoord(VertexHandle _vh) const override { #if defined(OM_CC_GCC) && (OM_CC_VERSION<30000) // Workaround! @@ -164,61 +182,109 @@ public: #endif } - Vec2f texcoord(HalfedgeHandle _heh) const + Vec2f texcoord(HalfedgeHandle _heh) const override { return (mesh_.has_halfedge_texcoords2D() ? vector_cast(mesh_.texcoord2D(_heh)) : Vec2f(0.0f, 0.0f)); } + OpenMesh::Attributes::StatusInfo status(VertexHandle _vh) const override + { + if (mesh_.has_vertex_status()) + return mesh_.status(_vh); + return OpenMesh::Attributes::StatusInfo(); + } + // get edge data - Vec3uc color(EdgeHandle _eh) const + Vec3uc color(EdgeHandle _eh) const override { return (mesh_.has_edge_colors() ? color_cast(mesh_.color(_eh)) : Vec3uc(0, 0, 0)); } - Vec4uc colorA(EdgeHandle _eh) const + Vec4uc colorA(EdgeHandle _eh) const override { return (mesh_.has_edge_colors() ? color_cast(mesh_.color(_eh)) : Vec4uc(0, 0, 0, 0)); } - Vec3ui colori(EdgeHandle _eh) const + Vec3ui colori(EdgeHandle _eh) const override { return (mesh_.has_edge_colors() ? color_cast(mesh_.color(_eh)) : Vec3ui(0, 0, 0)); } - Vec4ui colorAi(EdgeHandle _eh) const + Vec4ui colorAi(EdgeHandle _eh) const override { return (mesh_.has_edge_colors() ? color_cast(mesh_.color(_eh)) : Vec4ui(0, 0, 0, 0)); } - Vec3f colorf(EdgeHandle _eh) const + Vec3f colorf(EdgeHandle _eh) const override { return (mesh_.has_vertex_colors() ? color_cast(mesh_.color(_eh)) : Vec3f(0, 0, 0)); } - Vec4f colorAf(EdgeHandle _eh) const + Vec4f colorAf(EdgeHandle _eh) const override { return (mesh_.has_vertex_colors() ? color_cast(mesh_.color(_eh)) : Vec4f(0, 0, 0, 0)); } + OpenMesh::Attributes::StatusInfo status(EdgeHandle _eh) const override + { + if (mesh_.has_edge_status()) + return mesh_.status(_eh); + return OpenMesh::Attributes::StatusInfo(); + } + + // get halfedge data + + int get_halfedge_id(VertexHandle _vh) override + { + return mesh_.halfedge_handle(_vh).idx(); + } + + int get_halfedge_id(FaceHandle _fh) override + { + return mesh_.halfedge_handle(_fh).idx(); + } + + int get_next_halfedge_id(HalfedgeHandle _heh) override + { + return mesh_.next_halfedge_handle(_heh).idx(); + } + + int get_to_vertex_id(HalfedgeHandle _heh) override + { + return mesh_.to_vertex_handle(_heh).idx(); + } + + int get_face_id(HalfedgeHandle _heh) override + { + return mesh_.face_handle(_heh).idx(); + } + + OpenMesh::Attributes::StatusInfo status(HalfedgeHandle _heh) const override + { + if (mesh_.has_halfedge_status()) + return mesh_.status(_heh); + return OpenMesh::Attributes::StatusInfo(); + } + // get face data unsigned int get_vhandles(FaceHandle _fh, - std::vector& _vhandles) const + std::vector& _vhandles) const override { unsigned int count(0); _vhandles.clear(); @@ -230,7 +296,7 @@ public: return count; } - unsigned int get_face_texcoords(std::vector& _hehandles) const + unsigned int get_face_texcoords(std::vector& _hehandles) const override { unsigned int count(0); _hehandles.clear(); @@ -244,7 +310,7 @@ public: return count; } - HalfedgeHandle getHeh(FaceHandle _fh, VertexHandle _vh) const + HalfedgeHandle getHeh(FaceHandle _fh, VertexHandle _vh) const override { typename Mesh::ConstFaceHalfedgeIter fh_it; for(fh_it = mesh_.cfh_iter(_fh); fh_it.is_valid();++fh_it) @@ -255,74 +321,92 @@ public: return *fh_it; } - Vec3f normal(FaceHandle _fh) const + Vec3f normal(FaceHandle _fh) const override { return (mesh_.has_face_normals() ? vector_cast(mesh_.normal(_fh)) : Vec3f(0.0f, 0.0f, 0.0f)); } - Vec3uc color(FaceHandle _fh) const + Vec3d normald(FaceHandle _fh) const override + { + return (mesh_.has_face_normals() + ? vector_cast(mesh_.normal(_fh)) + : Vec3d(0.0, 0.0, 0.0)); + } + + Vec3uc color(FaceHandle _fh) const override { return (mesh_.has_face_colors() ? color_cast(mesh_.color(_fh)) : Vec3uc(0, 0, 0)); } - Vec4uc colorA(FaceHandle _fh) const + Vec4uc colorA(FaceHandle _fh) const override { return (mesh_.has_face_colors() ? color_cast(mesh_.color(_fh)) : Vec4uc(0, 0, 0, 0)); } - Vec3ui colori(FaceHandle _fh) const + Vec3ui colori(FaceHandle _fh) const override { return (mesh_.has_face_colors() ? color_cast(mesh_.color(_fh)) : Vec3ui(0, 0, 0)); } - Vec4ui colorAi(FaceHandle _fh) const + Vec4ui colorAi(FaceHandle _fh) const override { return (mesh_.has_face_colors() ? color_cast(mesh_.color(_fh)) : Vec4ui(0, 0, 0, 0)); } - Vec3f colorf(FaceHandle _fh) const + Vec3f colorf(FaceHandle _fh) const override { - return (mesh_.has_vertex_colors() + return (mesh_.has_face_colors() ? color_cast(mesh_.color(_fh)) : Vec3f(0, 0, 0)); } - Vec4f colorAf(FaceHandle _fh) const + Vec4f colorAf(FaceHandle _fh) const override { - return (mesh_.has_vertex_colors() + return (mesh_.has_face_colors() ? color_cast(mesh_.color(_fh)) : Vec4f(0, 0, 0, 0)); } - virtual const BaseKernel* kernel() { return &mesh_; } + OpenMesh::Attributes::StatusInfo status(FaceHandle _fh) const override + { + if (mesh_.has_face_status()) + return mesh_.status(_fh); + return OpenMesh::Attributes::StatusInfo(); + } + + virtual const BaseKernel* kernel() override { return &mesh_; } // query number of faces, vertices, normals, texcoords - size_t n_vertices() const { return mesh_.n_vertices(); } - size_t n_faces() const { return mesh_.n_faces(); } - size_t n_edges() const { return mesh_.n_edges(); } + size_t n_vertices() const override { return mesh_.n_vertices(); } + size_t n_faces() const override { return mesh_.n_faces(); } + size_t n_edges() const override { return mesh_.n_edges(); } // property information - bool is_triangle_mesh() const + bool is_triangle_mesh() const override { return Mesh::is_triangles(); } - bool has_vertex_normals() const { return mesh_.has_vertex_normals(); } - bool has_vertex_colors() const { return mesh_.has_vertex_colors(); } - bool has_vertex_texcoords() const { return mesh_.has_vertex_texcoords2D(); } - bool has_edge_colors() const { return mesh_.has_edge_colors(); } - bool has_face_normals() const { return mesh_.has_face_normals(); } - bool has_face_colors() const { return mesh_.has_face_colors(); } + bool has_vertex_normals() const override { return mesh_.has_vertex_normals(); } + bool has_vertex_colors() const override { return mesh_.has_vertex_colors(); } + bool has_vertex_texcoords() const override { return mesh_.has_vertex_texcoords2D(); } + bool has_vertex_status() const override { return mesh_.has_vertex_status(); } + bool has_edge_colors() const override { return mesh_.has_edge_colors(); } + bool has_edge_status() const override { return mesh_.has_edge_status(); } + bool has_halfedge_status() const override { return mesh_.has_halfedge_status(); } + bool has_face_normals() const override { return mesh_.has_face_normals(); } + bool has_face_colors() const override { return mesh_.has_face_colors(); } + bool has_face_status() const override { return mesh_.has_face_status(); } private: diff --git a/src/OpenMesh/Core/IO/importer/BaseImporter.hh b/src/OpenMesh/Core/IO/importer/BaseImporter.hh index afcfd6ca..53da0ed0 100644 --- a/src/OpenMesh/Core/IO/importer/BaseImporter.hh +++ b/src/OpenMesh/Core/IO/importer/BaseImporter.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= @@ -96,13 +91,22 @@ public: // add a vertex with coordinate \c _point virtual VertexHandle add_vertex(const Vec3f& _point) = 0; + // add a vertex with coordinate \c _point + virtual VertexHandle add_vertex(const Vec3d& _point) { return add_vertex(Vec3f(_point)); } + // add a vertex without coordinate. Use set_point to set the position deferred virtual VertexHandle add_vertex() = 0; + // add an edge. Use set_next, set_vertex and set_face to set corresponding entities for halfedges + virtual HalfedgeHandle add_edge(VertexHandle _vh0, VertexHandle _vh1) = 0; + // add a face with indices _indices refering to vertices typedef std::vector VHandles; virtual FaceHandle add_face(const VHandles& _indices) = 0; + // add a face with incident halfedge + virtual FaceHandle add_face(HalfedgeHandle _heh) = 0; + // add texture coordinates per face, _vh references the first texcoord virtual void add_face_texcoords( FaceHandle _fh, VertexHandle _vh, const std::vector& _face_texcoords) = 0; @@ -115,9 +119,15 @@ public: // Set coordinate of the given vertex. Use this function, if you created a vertex without coordinate virtual void set_point(VertexHandle _vh, const Vec3f& _point) = 0; + // Set outgoing halfedge for the given vertex. + virtual void set_halfedge(VertexHandle _vh, HalfedgeHandle _heh) = 0; + // set vertex normal virtual void set_normal(VertexHandle _vh, const Vec3f& _normal) = 0; + // set vertex normal + virtual void set_normal(VertexHandle _vh, const Vec3d& _normal) = 0; + // set vertex color virtual void set_color(VertexHandle _vh, const Vec3uc& _color) = 0; @@ -133,6 +143,15 @@ public: // set vertex texture coordinate virtual void set_texcoord(VertexHandle _vh, const Vec2f& _texcoord) = 0; + // set vertex status + virtual void set_status(VertexHandle _vh, const OpenMesh::Attributes::StatusInfo& _status) = 0; + + // set next halfedge handle + virtual void set_next(HalfedgeHandle _heh, HalfedgeHandle _next) = 0; + + // set incident face handle for given halfedge + virtual void set_face(HalfedgeHandle _heh, FaceHandle _fh) = 0; + // set vertex texture coordinate virtual void set_texcoord(HalfedgeHandle _heh, const Vec2f& _texcoord) = 0; @@ -142,6 +161,9 @@ public: // set 3d vertex texture coordinate virtual void set_texcoord(HalfedgeHandle _heh, const Vec3f& _texcoord) = 0; + // set halfedge status + virtual void set_status(HalfedgeHandle _heh, const OpenMesh::Attributes::StatusInfo& _status) = 0; + // set edge color virtual void set_color(EdgeHandle _eh, const Vec3uc& _color) = 0; @@ -154,9 +176,15 @@ public: // set edge color virtual void set_color(EdgeHandle _eh, const Vec4f& _color) = 0; + // set edge status + virtual void set_status(EdgeHandle _eh, const OpenMesh::Attributes::StatusInfo& _status) = 0; + // set face normal virtual void set_normal(FaceHandle _fh, const Vec3f& _normal) = 0; + // set face normal + virtual void set_normal(FaceHandle _fh, const Vec3d& _normal) = 0; + // set face color virtual void set_color(FaceHandle _fh, const Vec3uc& _color) = 0; @@ -169,12 +197,15 @@ public: // set face color virtual void set_color(FaceHandle _fh, const Vec4f& _color) = 0; + // set face status + virtual void set_status(FaceHandle _fh, const OpenMesh::Attributes::StatusInfo& _status) = 0; + // Store a property in the mesh mapping from an int to a texture file // Use set_face_texindex to set the index for each face virtual void add_texture_information( int _id , std::string _name ) = 0; // get reference to base kernel - virtual BaseKernel* kernel() { return 0; } + virtual BaseKernel* kernel() { return nullptr; } virtual bool is_triangle_mesh() const { return false; } diff --git a/src/OpenMesh/Core/IO/importer/ImporterT.hh b/src/OpenMesh/Core/IO/importer/ImporterT.hh index fb6b6690..93de5e1b 100644 --- a/src/OpenMesh/Core/IO/importer/ImporterT.hh +++ b/src/OpenMesh/Core/IO/importer/ImporterT.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= @@ -94,20 +89,30 @@ public: typedef std::vector VHandles; - ImporterT(Mesh& _mesh) : mesh_(_mesh), halfedgeNormals_() {} + explicit ImporterT(Mesh& _mesh) : mesh_(_mesh), halfedgeNormals_() {} - virtual VertexHandle add_vertex(const Vec3f& _point) + virtual VertexHandle add_vertex(const Vec3f& _point) override { return mesh_.add_vertex(vector_cast(_point)); } - virtual VertexHandle add_vertex() + virtual VertexHandle add_vertex(const Vec3d& _point) override + { + return mesh_.add_vertex(vector_cast(_point)); + } + + virtual VertexHandle add_vertex() override { return mesh_.new_vertex(); } - virtual FaceHandle add_face(const VHandles& _indices) + virtual HalfedgeHandle add_edge(VertexHandle _vh0, VertexHandle _vh1) override + { + return mesh_.new_edge(_vh0, _vh1); + } + + virtual FaceHandle add_face(const VHandles& _indices) override { FaceHandle fh; @@ -192,14 +197,26 @@ public: return fh; } + virtual FaceHandle add_face(HalfedgeHandle _heh) override + { + auto fh = mesh_.new_face(); + mesh_.set_halfedge_handle(fh, _heh); + return fh; + } + // vertex attributes - virtual void set_point(VertexHandle _vh, const Vec3f& _point) + virtual void set_point(VertexHandle _vh, const Vec3f& _point) override { mesh_.set_point(_vh,vector_cast(_point)); } - virtual void set_normal(VertexHandle _vh, const Vec3f& _normal) + virtual void set_halfedge(VertexHandle _vh, HalfedgeHandle _heh) override + { + mesh_.set_halfedge_handle(_vh, _heh); + } + + virtual void set_normal(VertexHandle _vh, const Vec3f& _normal) override { if (mesh_.has_vertex_normals()) mesh_.set_normal(_vh, vector_cast(_normal)); @@ -210,114 +227,169 @@ public: halfedgeNormals_[_vh] = vector_cast(_normal); } - virtual void set_color(VertexHandle _vh, const Vec4uc& _color) + virtual void set_normal(VertexHandle _vh, const Vec3d& _normal) override + { + if (mesh_.has_vertex_normals()) + mesh_.set_normal(_vh, vector_cast(_normal)); + + //saves normals for half edges. + //they will be written, when the face is added + if (mesh_.has_halfedge_normals()) + halfedgeNormals_[_vh] = vector_cast(_normal); + } + + virtual void set_color(VertexHandle _vh, const Vec4uc& _color) override { if (mesh_.has_vertex_colors()) mesh_.set_color(_vh, color_cast(_color)); } - virtual void set_color(VertexHandle _vh, const Vec3uc& _color) + virtual void set_color(VertexHandle _vh, const Vec3uc& _color) override { if (mesh_.has_vertex_colors()) mesh_.set_color(_vh, color_cast(_color)); } - virtual void set_color(VertexHandle _vh, const Vec4f& _color) + virtual void set_color(VertexHandle _vh, const Vec4f& _color) override { if (mesh_.has_vertex_colors()) mesh_.set_color(_vh, color_cast(_color)); } - virtual void set_color(VertexHandle _vh, const Vec3f& _color) + virtual void set_color(VertexHandle _vh, const Vec3f& _color) override { if (mesh_.has_vertex_colors()) mesh_.set_color(_vh, color_cast(_color)); } - virtual void set_texcoord(VertexHandle _vh, const Vec2f& _texcoord) + virtual void set_texcoord(VertexHandle _vh, const Vec2f& _texcoord) override { if (mesh_.has_vertex_texcoords2D()) mesh_.set_texcoord2D(_vh, vector_cast(_texcoord)); } - virtual void set_texcoord(HalfedgeHandle _heh, const Vec2f& _texcoord) + virtual void set_status(VertexHandle _vh, const OpenMesh::Attributes::StatusInfo& _status) override + { + if (!mesh_.has_vertex_status()) + mesh_.request_vertex_status(); + mesh_.status(_vh) = _status; + } + + virtual void set_next(HalfedgeHandle _heh, HalfedgeHandle _next) override + { + mesh_.set_next_halfedge_handle(_heh, _next); + } + + virtual void set_face(HalfedgeHandle _heh, FaceHandle _fh) override + { + mesh_.set_face_handle(_heh, _fh); + } + + + virtual void set_texcoord(HalfedgeHandle _heh, const Vec2f& _texcoord) override { if (mesh_.has_halfedge_texcoords2D()) mesh_.set_texcoord2D(_heh, vector_cast(_texcoord)); } - virtual void set_texcoord(VertexHandle _vh, const Vec3f& _texcoord) + virtual void set_texcoord(VertexHandle _vh, const Vec3f& _texcoord) override { if (mesh_.has_vertex_texcoords3D()) mesh_.set_texcoord3D(_vh, vector_cast(_texcoord)); } - virtual void set_texcoord(HalfedgeHandle _heh, const Vec3f& _texcoord) + virtual void set_texcoord(HalfedgeHandle _heh, const Vec3f& _texcoord) override { if (mesh_.has_halfedge_texcoords3D()) mesh_.set_texcoord3D(_heh, vector_cast(_texcoord)); } + virtual void set_status(HalfedgeHandle _heh, const OpenMesh::Attributes::StatusInfo& _status) override + { + if (!mesh_.has_halfedge_status()) + mesh_.request_halfedge_status(); + mesh_.status(_heh) = _status; + } // edge attributes - virtual void set_color(EdgeHandle _eh, const Vec4uc& _color) + virtual void set_color(EdgeHandle _eh, const Vec4uc& _color) override { if (mesh_.has_edge_colors()) mesh_.set_color(_eh, color_cast(_color)); } - virtual void set_color(EdgeHandle _eh, const Vec3uc& _color) + virtual void set_color(EdgeHandle _eh, const Vec3uc& _color) override { if (mesh_.has_edge_colors()) mesh_.set_color(_eh, color_cast(_color)); } - virtual void set_color(EdgeHandle _eh, const Vec4f& _color) + virtual void set_color(EdgeHandle _eh, const Vec4f& _color) override { if (mesh_.has_edge_colors()) mesh_.set_color(_eh, color_cast(_color)); } - virtual void set_color(EdgeHandle _eh, const Vec3f& _color) + virtual void set_color(EdgeHandle _eh, const Vec3f& _color) override { if (mesh_.has_edge_colors()) mesh_.set_color(_eh, color_cast(_color)); } + virtual void set_status(EdgeHandle _eh, const OpenMesh::Attributes::StatusInfo& _status) override + { + if (!mesh_.has_edge_status()) + mesh_.request_edge_status(); + mesh_.status(_eh) = _status; + } + // face attributes - virtual void set_normal(FaceHandle _fh, const Vec3f& _normal) + virtual void set_normal(FaceHandle _fh, const Vec3f& _normal) override { if (mesh_.has_face_normals()) mesh_.set_normal(_fh, vector_cast(_normal)); } - virtual void set_color(FaceHandle _fh, const Vec3uc& _color) + virtual void set_normal(FaceHandle _fh, const Vec3d& _normal) override + { + if (mesh_.has_face_normals()) + mesh_.set_normal(_fh, vector_cast(_normal)); + } + + virtual void set_color(FaceHandle _fh, const Vec3uc& _color) override { if (mesh_.has_face_colors()) mesh_.set_color(_fh, color_cast(_color)); } - virtual void set_color(FaceHandle _fh, const Vec4uc& _color) + virtual void set_color(FaceHandle _fh, const Vec4uc& _color) override { if (mesh_.has_face_colors()) mesh_.set_color(_fh, color_cast(_color)); } - virtual void set_color(FaceHandle _fh, const Vec3f& _color) + virtual void set_color(FaceHandle _fh, const Vec3f& _color) override { if (mesh_.has_face_colors()) mesh_.set_color(_fh, color_cast(_color)); } - virtual void set_color(FaceHandle _fh, const Vec4f& _color) + virtual void set_color(FaceHandle _fh, const Vec4f& _color) override { if (mesh_.has_face_colors()) mesh_.set_color(_fh, color_cast(_color)); } - virtual void add_face_texcoords( FaceHandle _fh, VertexHandle _vh, const std::vector& _face_texcoords) + virtual void set_status(FaceHandle _fh, const OpenMesh::Attributes::StatusInfo& _status) override + { + if (!mesh_.has_face_status()) + mesh_.request_face_status(); + mesh_.status(_fh) = _status; + } + + virtual void add_face_texcoords( FaceHandle _fh, VertexHandle _vh, const std::vector& _face_texcoords) override { // get first halfedge handle HalfedgeHandle cur_heh = mesh_.halfedge_handle(_fh); @@ -334,7 +406,7 @@ public: } } - virtual void add_face_texcoords( FaceHandle _fh, VertexHandle _vh, const std::vector& _face_texcoords) + virtual void add_face_texcoords( FaceHandle _fh, VertexHandle _vh, const std::vector& _face_texcoords) override { // get first halfedge handle HalfedgeHandle cur_heh = mesh_.halfedge_handle(_fh); @@ -351,13 +423,15 @@ public: } } - virtual void set_face_texindex( FaceHandle _fh, int _texId ) { + virtual void set_face_texindex( FaceHandle _fh, int _texId ) override + { if ( mesh_.has_face_texture_index() ) { mesh_.set_texture_index(_fh , _texId); } } - virtual void add_texture_information( int _id , std::string _name ) { + virtual void add_texture_information( int _id , std::string _name ) override + { OpenMesh::MPropHandleT< std::map< int, std::string > > property; if ( !mesh_.get_property_handle(property,"TextureMapping") ) { @@ -370,26 +444,26 @@ public: // low-level access to mesh - virtual BaseKernel* kernel() { return &mesh_; } + virtual BaseKernel* kernel() override { return &mesh_; } - bool is_triangle_mesh() const + bool is_triangle_mesh() const override { return Mesh::is_triangles(); } - void reserve(unsigned int nV, unsigned int nE, unsigned int nF) + void reserve(unsigned int nV, unsigned int nE, unsigned int nF) override { mesh_.reserve(nV, nE, nF); } // query number of faces, vertices, normals, texcoords - size_t n_vertices() const { return mesh_.n_vertices(); } - size_t n_faces() const { return mesh_.n_faces(); } - size_t n_edges() const { return mesh_.n_edges(); } + size_t n_vertices() const override { return mesh_.n_vertices(); } + size_t n_faces() const override { return mesh_.n_faces(); } + size_t n_edges() const override { return mesh_.n_edges(); } - void prepare() { } + void prepare() override{ } - void finish() { } + void finish() override { } private: diff --git a/src/OpenMesh/Core/IO/reader/BaseReader.cc b/src/OpenMesh/Core/IO/reader/BaseReader.cc index d1cc8d94..d7bc0946 100644 --- a/src/OpenMesh/Core/IO/reader/BaseReader.cc +++ b/src/OpenMesh/Core/IO/reader/BaseReader.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //=== INCLUDES ================================================================ diff --git a/src/OpenMesh/Core/IO/reader/BaseReader.hh b/src/OpenMesh/Core/IO/reader/BaseReader.hh index d1eddfc9..9f6c23bb 100644 --- a/src/OpenMesh/Core/IO/reader/BaseReader.hh +++ b/src/OpenMesh/Core/IO/reader/BaseReader.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= @@ -53,10 +48,7 @@ // //============================================================================= - -#ifndef __BASEREADER_HH__ -#define __BASEREADER_HH__ - +#pragma once //=== INCLUDES ================================================================ @@ -96,7 +88,7 @@ class OPENMESHDLLEXPORT BaseReader public: /// Destructor - virtual ~BaseReader() {}; + virtual ~BaseReader() {} /// Returns a brief description of the file type that can be parsed. virtual std::string get_description() const = 0; @@ -156,7 +148,16 @@ protected: * @return trimmed string */ static inline std::string &left_trim(std::string &_string) { - _string.erase(_string.begin(), std::find_if(_string.begin(), _string.end(), std::not1(std::ptr_fun(std::isspace)))); + + // Find out if the compiler supports CXX11 + #if ( __cplusplus >= 201103L || _MSVC_LANG >= 201103L ) + // as with CXX11 we can use lambda expressions + _string.erase(_string.begin(), std::find_if(_string.begin(), _string.end(), [](int i)->int { return ! std::isspace(i); })); + #else + // we do what we did before + _string.erase(_string.begin(), std::find_if(_string.begin(), _string.end(), std::not1(std::ptr_fun(std::isspace)))); + #endif + return _string; } @@ -168,7 +169,18 @@ static inline std::string &left_trim(std::string &_string) { * @return trimmed string */ static inline std::string &right_trim(std::string &_string) { - _string.erase(std::find_if(_string.rbegin(), _string.rend(), std::not1(std::ptr_fun(std::isspace))).base(), _string.end()); + + // Find out if the compiler supports CXX11 + #if ( __cplusplus >= 201103L || _MSVC_LANG >= 201103L ) + // as with CXX11 we can use lambda expressions + _string.erase(std::find_if(_string.rbegin(), _string.rend(), [](int i)->int { return ! std::isspace(i); } ).base(), _string.end()); + #else + // we do what we did before + _string.erase(std::find_if(_string.rbegin(), _string.rend(), std::not1(std::ptr_fun(std::isspace))).base(), _string.end()); + #endif + + + return _string; } @@ -189,5 +201,3 @@ static inline std::string &trim(std::string &_string) { } // namespace IO } // namespace OpenMesh //============================================================================= -#endif -//============================================================================= diff --git a/src/OpenMesh/Core/IO/reader/OBJReader.cc b/src/OpenMesh/Core/IO/reader/OBJReader.cc index 4128b231..bdefcd7d 100644 --- a/src/OpenMesh/Core/IO/reader/OBJReader.cc +++ b/src/OpenMesh/Core/IO/reader/OBJReader.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //== INCLUDES ================================================================= @@ -140,13 +135,13 @@ read(const std::string& _filename, BaseImporter& _bi, Options& _opt) { #if defined(WIN32) - std::string::size_type dot = _filename.find_last_of("\\/"); + std::string::size_type dot_pos = _filename.find_last_of("\\/"); #else - std::string::size_type dot = _filename.rfind("/"); + std::string::size_type dot_pos = _filename.rfind("/"); #endif - path_ = (dot == std::string::npos) + path_ = (dot_pos == std::string::npos) ? "./" - : std::string(_filename.substr(0,dot+1)); + : std::string(_filename.substr(0,dot_pos+1)); } bool result = read(in, _bi, _opt); @@ -540,6 +535,7 @@ read(std::istream& _in, BaseImporter& _bi, Options& _opt) vhandles.clear(); face_texcoords.clear(); + face_texcoords3d.clear(); // read full line after detecting a face std::string faceLine; diff --git a/src/OpenMesh/Core/IO/reader/OBJReader.hh b/src/OpenMesh/Core/IO/reader/OBJReader.hh index 70c3a2fe..2de77bc4 100644 --- a/src/OpenMesh/Core/IO/reader/OBJReader.hh +++ b/src/OpenMesh/Core/IO/reader/OBJReader.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= @@ -92,16 +87,16 @@ public: virtual ~_OBJReader_() { } - std::string get_description() const { return "Alias/Wavefront"; } - std::string get_extensions() const { return "obj"; } + std::string get_description() const override { return "Alias/Wavefront"; } + std::string get_extensions() const override { return "obj"; } bool read(const std::string& _filename, BaseImporter& _bi, - Options& _opt); + Options& _opt) override; bool read(std::istream& _in, BaseImporter& _bi, - Options& _opt); + Options& _opt) override; private: @@ -110,7 +105,7 @@ private: { public: - Material() { cleanup(); } + Material():Tr_(0),index_Kd_(0) { cleanup(); } void cleanup() { @@ -142,7 +137,7 @@ private: void set_Tr( float t ) { Tr_=t; Tr_is_set_=true; } - void set_map_Kd( std::string _name, int _index_Kd ) + void set_map_Kd( const std::string& _name, int _index_Kd ) { map_Kd_ = _name, index_Kd_ = _index_Kd; map_Kd_is_set_ = true; }; const Vec3f& Kd( void ) const { return Kd_; } diff --git a/src/OpenMesh/Core/IO/reader/OFFReader.cc b/src/OpenMesh/Core/IO/reader/OFFReader.cc index 896b9994..e4a239ff 100644 --- a/src/OpenMesh/Core/IO/reader/OFFReader.cc +++ b/src/OpenMesh/Core/IO/reader/OFFReader.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #define LINE_LEN 4096 diff --git a/src/OpenMesh/Core/IO/reader/OFFReader.hh b/src/OpenMesh/Core/IO/reader/OFFReader.hh index 755093a3..2efe6e4a 100644 --- a/src/OpenMesh/Core/IO/reader/OFFReader.hh +++ b/src/OpenMesh/Core/IO/reader/OFFReader.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= @@ -53,10 +48,7 @@ // //============================================================================= - -#ifndef __OFFREADER_HH__ -#define __OFFREADER_HH__ - +#pragma once //=== INCLUDES ================================================================ @@ -123,17 +115,17 @@ public: /// Destructor virtual ~_OFFReader_() {}; - std::string get_description() const { return "Object File Format"; } - std::string get_extensions() const { return "off"; } - std::string get_magic() const { return "OFF"; } + std::string get_description() const override { return "Object File Format"; } + std::string get_extensions() const override { return "off"; } + std::string get_magic() const override { return "OFF"; } bool read(const std::string& _filename, BaseImporter& _bi, - Options& _opt); + Options& _opt) override; - bool can_u_read(const std::string& _filename) const; + bool can_u_read(const std::string& _filename) const override; - bool read(std::istream& _in, BaseImporter& _bi, Options& _opt ); + bool read(std::istream& _in, BaseImporter& _bi, Options& _opt ) override; private: @@ -167,5 +159,3 @@ OPENMESHDLLEXPORT _OFFReader_& OFFReader(); } // namespace IO } // namespace OpenMesh //============================================================================= -#endif -//============================================================================= diff --git a/src/OpenMesh/Core/IO/reader/OMReader.cc b/src/OpenMesh/Core/IO/reader/OMReader.cc index b66684eb..66d4e819 100644 --- a/src/OpenMesh/Core/IO/reader/OMReader.cc +++ b/src/OpenMesh/Core/IO/reader/OMReader.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //== INCLUDES ================================================================= @@ -61,6 +56,7 @@ #include #include #include +#include //=== NAMESPACES ============================================================== @@ -176,6 +172,15 @@ bool _OMReader_::read_binary(std::istream& _is, BaseImporter& _bi, Options& _opt bytes_ += restore(_is, header_, swap); + if (header_.version_ > _OMWriter_::get_version()) + { + omerr() << "File uses .om version " << OMFormat::as_string(header_.version_) << " but reader only " + << "supports up to version " << OMFormat::as_string(_OMWriter_::get_version()) << ".\n" + << "Please update your OpenMesh." << std::endl; + return false; + } + + while (!_is.eof()) { bytes_ += restore(_is, chunk_header_, swap); @@ -292,30 +297,67 @@ bool _OMReader_::read_binary_vertex_chunk(std::istream &_is, BaseImporter &_bi, assert( chunk_header_.entity_ == Chunk::Entity_Vertex); OpenMesh::Vec3f v3f; + OpenMesh::Vec3d v3d; OpenMesh::Vec2f v2f; OpenMesh::Vec3uc v3uc; // rgb + OpenMesh::Attributes::StatusInfo status; OMFormat::Chunk::PropertyName custom_prop; size_t vidx = 0; switch (chunk_header_.type_) { case Chunk::Type_Pos: - assert( OMFormat::dimensions(chunk_header_) == size_t(OpenMesh::Vec3f::dim())); + if (chunk_header_.bits_ == OMFormat::bits(0.0f)) // read floats + { + assert( OMFormat::dimensions(chunk_header_) == size_t(OpenMesh::Vec3f::dim())); - for (; vidx < header_.n_vertices_ && !_is.eof(); ++vidx) { - bytes_ += vector_restore(_is, v3f, _swap); - _bi.add_vertex(v3f); + for (; vidx < header_.n_vertices_ && !_is.eof(); ++vidx) { + bytes_ += vector_restore(_is, v3f, _swap); + _bi.add_vertex(v3f); + } + } + else if (chunk_header_.bits_ == OMFormat::bits(0.0)) // read doubles + { + assert( OMFormat::dimensions(chunk_header_) == size_t(OpenMesh::Vec3d::dim())); + + for (; vidx < header_.n_vertices_ && !_is.eof(); ++vidx) { + bytes_ += vector_restore(_is, v3d, _swap); + _bi.add_vertex(v3d); + } + } + else + { + omerr() << "unknown Vector size" << std::endl; } break; case Chunk::Type_Normal: - assert( OMFormat::dimensions(chunk_header_) == size_t(OpenMesh::Vec3f::dim())); - fileOptions_ += Options::VertexNormal; - for (; vidx < header_.n_vertices_ && !_is.eof(); ++vidx) { - bytes_ += vector_restore(_is, v3f, _swap); - if (fileOptions_.vertex_has_normal() && _opt.vertex_has_normal()) - _bi.set_normal(VertexHandle(int(vidx)), v3f); + if (chunk_header_.bits_ == OMFormat::bits(0.0f)) // read floats + { + assert( OMFormat::dimensions(chunk_header_) == size_t(OpenMesh::Vec3f::dim())); + + fileOptions_ += Options::VertexNormal; + for (; vidx < header_.n_vertices_ && !_is.eof(); ++vidx) { + bytes_ += vector_restore(_is, v3f, _swap); + if (fileOptions_.vertex_has_normal() && _opt.vertex_has_normal()) + _bi.set_normal(VertexHandle(int(vidx)), v3f); + } + } + else if (chunk_header_.bits_ == OMFormat::bits(0.0)) // read doubles + { + assert( OMFormat::dimensions(chunk_header_) == size_t(OpenMesh::Vec3d::dim())); + + fileOptions_ += Options::VertexNormal; + for (; vidx < header_.n_vertices_ && !_is.eof(); ++vidx) { + bytes_ += vector_restore(_is, v3d, _swap); + if (fileOptions_.vertex_has_normal() && _opt.vertex_has_normal()) + _bi.set_normal(VertexHandle(int(vidx)), v3d); + } + } + else + { + omerr() << "Unknown vertex normal format" << std::endl; } break; @@ -343,6 +385,20 @@ bool _OMReader_::read_binary_vertex_chunk(std::istream &_is, BaseImporter &_bi, } break; + case Chunk::Type_Status: + { + assert( OMFormat::dimensions(chunk_header_) == 1); + + fileOptions_ += Options::Status; + + for (; vidx < header_.n_vertices_ && !_is.eof(); ++vidx) { + bytes_ += restore(_is, status, _swap); + if (fileOptions_.vertex_has_status() && _opt.vertex_has_status()) + _bi.set_status(VertexHandle(int(vidx)), status); + } + break; + } + case Chunk::Type_Custom: bytes_ += restore_binary_custom_data(_is, _bi.kernel()->_get_vprop(property_name_), header_.n_vertices_, _swap); @@ -351,13 +407,28 @@ bool _OMReader_::read_binary_vertex_chunk(std::istream &_is, BaseImporter &_bi, break; + case Chunk::Type_Topology: + { + for (; vidx < header_.n_vertices_; ++vidx) + { + int halfedge_id = 0; + bytes_ += restore( _is, halfedge_id, OMFormat::Chunk::Integer_Size(chunk_header_.bits_), _swap ); + + _bi.set_halfedge(VertexHandle(static_cast(vidx)), HalfedgeHandle(halfedge_id)); + } + } + + break; + default: // skip unknown chunks { omerr() << "Unknown chunk type ignored!\n"; - size_t size_of = header_.n_vertices_ * OMFormat::vector_size(chunk_header_); - _is.ignore(size_of); - bytes_ += size_of; + size_t chunk_size = header_.n_vertices_ * OMFormat::vector_size(chunk_header_); + _is.ignore(chunk_size); + bytes_ += chunk_size; + break; } + } // all chunk data has been read..?! @@ -375,35 +446,53 @@ bool _OMReader_::read_binary_face_chunk(std::istream &_is, BaseImporter &_bi, Op size_t fidx = 0; OpenMesh::Vec3f v3f; // normal + OpenMesh::Vec3d v3d; // normal as double OpenMesh::Vec3uc v3uc; // rgb + OpenMesh::Attributes::StatusInfo status; switch (chunk_header_.type_) { - case Chunk::Type_Topology: { - BaseImporter::VHandles vhandles; - size_t nV = 0; - size_t vidx = 0; + case Chunk::Type_Topology: + { + if (header_.version_ < OMFormat::mk_version(2,0)) + { + // add faces based on vertex indices + BaseImporter::VHandles vhandles; + size_t nV = 0; + size_t vidx = 0; - switch (header_.mesh_) { - case 'T': - nV = 3; - break; - case 'Q': - nV = 4; - break; - } - - for (; fidx < header_.n_faces_; ++fidx) { - if (header_.mesh_ == 'P') - bytes_ += restore(_is, nV, Chunk::Integer_16, _swap); - - vhandles.clear(); - for (size_t j = 0; j < nV; ++j) { - bytes_ += restore(_is, vidx, Chunk::Integer_Size(chunk_header_.bits_), _swap); - - vhandles.push_back(VertexHandle(int(vidx))); + switch (header_.mesh_) { + case 'T': + nV = 3; + break; + case 'Q': + nV = 4; + break; } - _bi.add_face(vhandles); + for (; fidx < header_.n_faces_; ++fidx) { + if (header_.mesh_ == 'P') + bytes_ += restore(_is, nV, Chunk::Integer_16, _swap); + + vhandles.clear(); + for (size_t j = 0; j < nV; ++j) { + bytes_ += restore(_is, vidx, Chunk::Integer_Size(chunk_header_.bits_), _swap); + + vhandles.push_back(VertexHandle(int(vidx))); + } + + _bi.add_face(vhandles); + } + } + else + { + // add faces by simply setting an incident halfedge + for (; fidx < header_.n_faces_; ++fidx) + { + int halfedge_id = 0; + bytes_ += restore( _is, halfedge_id, OMFormat::Chunk::Integer_Size(chunk_header_.bits_), _swap ); + + _bi.add_face(HalfedgeHandle(halfedge_id)); + } } } break; @@ -412,10 +501,26 @@ bool _OMReader_::read_binary_face_chunk(std::istream &_is, BaseImporter &_bi, Op assert( OMFormat::dimensions(chunk_header_) == size_t(OpenMesh::Vec3f::dim())); fileOptions_ += Options::FaceNormal; - for (; fidx < header_.n_faces_ && !_is.eof(); ++fidx) { - bytes_ += vector_restore(_is, v3f, _swap); - if( fileOptions_.face_has_normal() && _opt.face_has_normal()) - _bi.set_normal(FaceHandle(int(fidx)), v3f); + + if (chunk_header_.bits_ == OMFormat::bits(0.0f)) // read floats + { + for (; fidx < header_.n_faces_ && !_is.eof(); ++fidx) { + bytes_ += vector_restore(_is, v3f, _swap); + if( fileOptions_.face_has_normal() && _opt.face_has_normal()) + _bi.set_normal(FaceHandle(int(fidx)), v3f); + } + } + else if (chunk_header_.bits_ == OMFormat::bits(0.0)) // read doubles + { + for (; fidx < header_.n_faces_ && !_is.eof(); ++fidx) { + bytes_ += vector_restore(_is, v3d, _swap); + if( fileOptions_.face_has_normal() && _opt.face_has_normal()) + _bi.set_normal(FaceHandle(int(fidx)), v3d); + } + } + else + { + omerr() << "Unknown face normal format" << std::endl; } break; @@ -430,6 +535,19 @@ bool _OMReader_::read_binary_face_chunk(std::istream &_is, BaseImporter &_bi, Op _bi.set_color(FaceHandle(int(fidx)), v3uc); } break; + case Chunk::Type_Status: + { + assert( OMFormat::dimensions(chunk_header_) == 1); + + fileOptions_ += Options::Status; + + for (; fidx < header_.n_faces_ && !_is.eof(); ++fidx) { + bytes_ += restore(_is, status, _swap); + if (fileOptions_.face_has_status() && _opt.face_has_status()) + _bi.set_status(FaceHandle(int(fidx)), status); + } + break; + } case Chunk::Type_Custom: @@ -442,9 +560,9 @@ bool _OMReader_::read_binary_face_chunk(std::istream &_is, BaseImporter &_bi, Op default: // skip unknown chunks { omerr() << "Unknown chunk type ignore!\n"; - size_t size_of = OMFormat::chunk_data_size(header_, chunk_header_); - _is.ignore(size_of); - bytes_ += size_of; + size_t chunk_size = OMFormat::chunk_data_size(header_, chunk_header_); + _is.ignore(chunk_size); + bytes_ += chunk_size; } } return fidx == header_.n_faces_; @@ -453,7 +571,7 @@ bool _OMReader_::read_binary_face_chunk(std::istream &_is, BaseImporter &_bi, Op //----------------------------------------------------------------------------- -bool _OMReader_::read_binary_edge_chunk(std::istream &_is, BaseImporter &_bi, Options &/*_opt */, bool _swap) const +bool _OMReader_::read_binary_edge_chunk(std::istream &_is, BaseImporter &_bi, Options &_opt, bool _swap) const { using OMFormat::Chunk; @@ -461,6 +579,8 @@ bool _OMReader_::read_binary_edge_chunk(std::istream &_is, BaseImporter &_bi, Op size_t b = bytes_; + OpenMesh::Attributes::StatusInfo status; + switch (chunk_header_.type_) { case Chunk::Type_Custom: @@ -468,11 +588,25 @@ bool _OMReader_::read_binary_edge_chunk(std::istream &_is, BaseImporter &_bi, Op break; + case Chunk::Type_Status: + { + assert( OMFormat::dimensions(chunk_header_) == 1); + + fileOptions_ += Options::Status; + + for (size_t eidx = 0; eidx < header_.n_edges_ && !_is.eof(); ++eidx) { + bytes_ += restore(_is, status, _swap); + if (fileOptions_.edge_has_status() && _opt.edge_has_status()) + _bi.set_status(EdgeHandle(int(eidx)), status); + } + break; + } + default: // skip unknown type - size_t size_of = OMFormat::chunk_data_size(header_, chunk_header_); - _is.ignore(size_of); - bytes_ += size_of; + size_t chunk_size = OMFormat::chunk_data_size(header_, chunk_header_); + _is.ignore(chunk_size); + bytes_ += chunk_size; } return b < bytes_; @@ -481,13 +615,14 @@ bool _OMReader_::read_binary_edge_chunk(std::istream &_is, BaseImporter &_bi, Op //----------------------------------------------------------------------------- -bool _OMReader_::read_binary_halfedge_chunk(std::istream &_is, BaseImporter &_bi, Options &/* _opt */, bool _swap) const +bool _OMReader_::read_binary_halfedge_chunk(std::istream &_is, BaseImporter &_bi, Options & _opt, bool _swap) const { using OMFormat::Chunk; assert( chunk_header_.entity_ == Chunk::Entity_Halfedge); size_t b = bytes_; + OpenMesh::Attributes::StatusInfo status; switch (chunk_header_.type_) { case Chunk::Type_Custom: @@ -495,12 +630,61 @@ bool _OMReader_::read_binary_halfedge_chunk(std::istream &_is, BaseImporter &_bi bytes_ += restore_binary_custom_data(_is, _bi.kernel()->_get_hprop(property_name_), 2 * header_.n_edges_, _swap); break; + case Chunk::Type_Topology: + { + std::vector next_halfedges; + for (size_t e_idx = 0; e_idx < header_.n_edges_; ++e_idx) + { + int next_id_0 = -1; + int to_vertex_id_0 = -1; + int face_id_0 = -1; + bytes_ += restore( _is, next_id_0, OMFormat::Chunk::Integer_Size(chunk_header_.bits_), _swap ); + bytes_ += restore( _is, to_vertex_id_0, OMFormat::Chunk::Integer_Size(chunk_header_.bits_), _swap ); + bytes_ += restore( _is, face_id_0, OMFormat::Chunk::Integer_Size(chunk_header_.bits_), _swap ); + + int next_id_1 = -1; + int to_vertex_id_1 = -1; + int face_id_1 = -1; + bytes_ += restore( _is, next_id_1, OMFormat::Chunk::Integer_Size(chunk_header_.bits_), _swap ); + bytes_ += restore( _is, to_vertex_id_1, OMFormat::Chunk::Integer_Size(chunk_header_.bits_), _swap ); + bytes_ += restore( _is, face_id_1, OMFormat::Chunk::Integer_Size(chunk_header_.bits_), _swap ); + + auto heh0 = _bi.add_edge(VertexHandle(to_vertex_id_1), VertexHandle(to_vertex_id_0)); + auto heh1 = HalfedgeHandle(heh0.idx() + 1); + + next_halfedges.push_back(HalfedgeHandle(next_id_0)); + next_halfedges.push_back(HalfedgeHandle(next_id_1)); + + _bi.set_face(heh0, FaceHandle(face_id_0)); + _bi.set_face(heh1, FaceHandle(face_id_1)); + } + + for (size_t i = 0; i < next_halfedges.size(); ++i) + _bi.set_next(HalfedgeHandle(static_cast(i)), next_halfedges[i]); + } + + break; + + case Chunk::Type_Status: + { + assert( OMFormat::dimensions(chunk_header_) == 1); + + fileOptions_ += Options::Status; + + for (size_t hidx = 0; hidx < header_.n_edges_ * 2 && !_is.eof(); ++hidx) { + bytes_ += restore(_is, status, _swap); + if (fileOptions_.halfedge_has_status() && _opt.halfedge_has_status()) + _bi.set_status(HalfedgeHandle(int(hidx)), status); + } + break; + } + default: // skip unknown chunk omerr() << "Unknown chunk type ignored!\n"; - size_t size_of = OMFormat::chunk_data_size(header_, chunk_header_); - _is.ignore(size_of); - bytes_ += size_of; + size_t chunk_size = OMFormat::chunk_data_size(header_, chunk_header_); + _is.ignore(chunk_size); + bytes_ += chunk_size; } return b < bytes_; @@ -526,9 +710,9 @@ bool _OMReader_::read_binary_mesh_chunk(std::istream &_is, BaseImporter &_bi, Op default: // skip unknown chunk - size_t size_of = OMFormat::chunk_data_size(header_, chunk_header_); - _is.ignore(size_of); - bytes_ += size_of; + size_t chunk_size = OMFormat::chunk_data_size(header_, chunk_header_); + _is.ignore(chunk_size); + bytes_ += chunk_size; } return b < bytes_; diff --git a/src/OpenMesh/Core/IO/reader/OMReader.hh b/src/OpenMesh/Core/IO/reader/OMReader.hh index 4b1f67db..5e04e378 100644 --- a/src/OpenMesh/Core/IO/reader/OMReader.hh +++ b/src/OpenMesh/Core/IO/reader/OMReader.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= @@ -94,20 +89,20 @@ public: _OMReader_(); virtual ~_OMReader_() { } - std::string get_description() const { return "OpenMesh File Format"; } - std::string get_extensions() const { return "om"; } - std::string get_magic() const { return "OM"; } + std::string get_description() const override { return "OpenMesh File Format"; } + std::string get_extensions() const override { return "om"; } + std::string get_magic() const override { return "OM"; } bool read(const std::string& _filename, BaseImporter& _bi, - Options& _opt ); + Options& _opt ) override; //! Stream Reader for std::istream input in binary format bool read(std::istream& _is, BaseImporter& _bi, - Options& _opt ); + Options& _opt ) override; - virtual bool can_u_read(const std::string& _filename) const; + virtual bool can_u_read(const std::string& _filename) const override; virtual bool can_u_read(std::istream& _is) const; diff --git a/src/OpenMesh/Core/IO/reader/PLYReader.cc b/src/OpenMesh/Core/IO/reader/PLYReader.cc index 107fafa7..db431c14 100644 --- a/src/OpenMesh/Core/IO/reader/PLYReader.cc +++ b/src/OpenMesh/Core/IO/reader/PLYReader.cc @@ -39,13 +39,6 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * - \*===========================================================================*/ - #define LINE_LEN 4096 //== INCLUDES ================================================================= @@ -135,6 +128,14 @@ bool _PLYReader_::read(std::istream& _in, BaseImporter& _bi, Options& _opt) { return false; } + // Reparse the header + if (!can_u_read(_in)) { + omerr() << "[PLYReader] : Unable to parse header\n"; + return false; + } + + + // filter relevant options for reading bool swap = _opt.check(Options::Swap); @@ -218,16 +219,13 @@ void _PLYReader_::readCreateCustomProperty(std::istream& _in, BaseImporter& _bi, } //init vector - int numberOfValues; - read(_listType, _in, numberOfValues, OpenMesh::GenProg::Bool2Type()); - std::vector vec; - vec.reserve(numberOfValues); + unsigned int numberOfValues; + readInteger(_listType, _in, numberOfValues, OpenMesh::GenProg::Bool2Type()); + std::vector vec(numberOfValues); //read and assign - for (int i = 0; i < numberOfValues; ++i) + for (unsigned int i = 0; i < numberOfValues; ++i) { - T in; - read(_valueType, _in, in, OpenMesh::GenProg::Bool2Type()); - vec.push_back(in); + read(_valueType, _in, vec[i], OpenMesh::GenProg::Bool2Type()); } _bi.kernel()->property(prop,_h) = vec; } @@ -281,12 +279,6 @@ void _PLYReader_::readCustomProperty(std::istream& _in, BaseImporter& _bi, Handl bool _PLYReader_::read_ascii(std::istream& _in, BaseImporter& _bi, const Options& _opt) const { - // Reparse the header - if (!can_u_read(_in)) { - omerr() << "[PLYReader] : Unable to parse header\n"; - return false; - } - unsigned int i, j, k, l, idx; unsigned int nV; OpenMesh::Vec3f v, n; @@ -311,6 +303,14 @@ bool _PLYReader_::read_ascii(std::istream& _in, BaseImporter& _bi, const Options for (std::vector::iterator e_it = elements_.begin(); e_it != elements_.end(); ++e_it) { + if (_in.eof()) { + if (err_enabled) + omerr().enable(); + + omerr() << "Unexpected end of file while reading." << std::endl; + return false; + } + if (e_it->element_== VERTEX) { // read vertices: @@ -422,6 +422,12 @@ bool _PLYReader_::read_ascii(std::istream& _in, BaseImporter& _bi, const Options // faces for (i = 0; i < faceCount_ && !_in.eof(); ++i) { FaceHandle fh; + + c[0] = 0; + c[1] = 0; + c[2] = 0; + c[3] = 255; + for (size_t propertyIndex = 0; propertyIndex < e_it->properties_.size(); ++propertyIndex) { PropertyInfo prop = e_it->properties_[propertyIndex]; switch (prop.property) { @@ -453,6 +459,38 @@ bool _PLYReader_::read_ascii(std::istream& _in, BaseImporter& _bi, const Options ++complex_faces; break; + case COLORRED: + if (prop.value == ValueTypeFLOAT32 || prop.value == ValueTypeFLOAT) { + _in >> tmp; + c[0] = static_cast (tmp * 255.0f); + } else + _in >> c[0]; + break; + + case COLORGREEN: + if (prop.value == ValueTypeFLOAT32 || prop.value == ValueTypeFLOAT) { + _in >> tmp; + c[1] = static_cast (tmp * 255.0f); + } else + _in >> c[1]; + break; + + case COLORBLUE: + if (prop.value == ValueTypeFLOAT32 || prop.value == ValueTypeFLOAT) { + _in >> tmp; + c[2] = static_cast (tmp * 255.0f); + } else + _in >> c[2]; + break; + + case COLORALPHA: + if (prop.value == ValueTypeFLOAT32 || prop.value == ValueTypeFLOAT) { + _in >> tmp; + c[3] = static_cast (tmp * 255.0f); + } else + _in >> c[3]; + break; + case CUSTOM_PROP: if (_opt.check(Options::Custom) && fh.is_valid()) readCustomProperty(_in, _bi, fh, prop.name, prop.value, prop.listIndexType); @@ -465,7 +503,8 @@ bool _PLYReader_::read_ascii(std::istream& _in, BaseImporter& _bi, const Options break; } } - + if (_opt.face_has_color()) + _bi.set_color(fh, Vec4uc(c)); } } else @@ -480,14 +519,6 @@ bool _PLYReader_::read_ascii(std::istream& _in, BaseImporter& _bi, const Options } } - if (_in.eof()) { - if (err_enabled) - omerr().enable(); - - omerr() << "Unexpected end of file while reading." << std::endl; - return false; - } - if(e_it->element_== FACE) // stop reading after the faces since additional elements are not preserved anyway break; @@ -507,12 +538,6 @@ bool _PLYReader_::read_ascii(std::istream& _in, BaseImporter& _bi, const Options bool _PLYReader_::read_binary(std::istream& _in, BaseImporter& _bi, bool /*_swap*/, const Options& _opt) const { - // Reparse the header - if (!can_u_read(_in)) { - omerr() << "[PLYReader] : Unable to parse header\n"; - return false; - } - OpenMesh::Vec3f v, n; // Vertex OpenMesh::Vec2f t; // TexCoords BaseImporter::VHandles vhandles; @@ -579,29 +604,26 @@ bool _PLYReader_::read_binary(std::istream& _in, BaseImporter& _bi, bool /*_swap readValue(prop.value, _in, t[1]); break; case COLORRED: - if (prop.value == ValueTypeFLOAT32 || - prop.value == ValueTypeFLOAT) { - readValue(prop.value, _in, tmp); + if (prop.value == ValueTypeFLOAT32 || prop.value == ValueTypeFLOAT) { + readValue(prop.value, _in, tmp); - c[0] = static_cast (tmp * 255.0f); + c[0] = static_cast (tmp * 255.0f); } else - readInteger(prop.value, _in, c[0]); + readInteger(prop.value, _in, c[0]); break; case COLORGREEN: - if (prop.value == ValueTypeFLOAT32 || - prop.value == ValueTypeFLOAT) { - readValue(prop.value, _in, tmp); - c[1] = static_cast (tmp * 255.0f); - } - else - readInteger(prop.value, _in, c[1]); + if (prop.value == ValueTypeFLOAT32 || prop.value == ValueTypeFLOAT) { + readValue(prop.value, _in, tmp); + c[1] = static_cast (tmp * 255.0f); + } + else + readInteger(prop.value, _in, c[1]); break; case COLORBLUE: - if (prop.value == ValueTypeFLOAT32 || - prop.value == ValueTypeFLOAT) { + if (prop.value == ValueTypeFLOAT32 || prop.value == ValueTypeFLOAT) { readValue(prop.value, _in, tmp); c[2] = static_cast (tmp * 255.0f); } @@ -610,8 +632,7 @@ bool _PLYReader_::read_binary(std::istream& _in, BaseImporter& _bi, bool /*_swap break; case COLORALPHA: - if (prop.value == ValueTypeFLOAT32 || - prop.value == ValueTypeFLOAT) { + if (prop.value == ValueTypeFLOAT32 || prop.value == ValueTypeFLOAT) { readValue(prop.value, _in, tmp); c[3] = static_cast (tmp * 255.0f); } @@ -645,6 +666,12 @@ bool _PLYReader_::read_binary(std::istream& _in, BaseImporter& _bi, bool /*_swap else if (e_it->element_ == FACE) { for (unsigned i = 0; i < e_it->count_ && !_in.eof(); ++i) { FaceHandle fh; + + c[0] = 0; + c[1] = 0; + c[2] = 0; + c[3] = 255; + for (size_t propertyIndex = 0; propertyIndex < e_it->properties_.size(); ++propertyIndex) { PropertyInfo prop = e_it->properties_[propertyIndex]; @@ -679,7 +706,38 @@ bool _PLYReader_::read_binary(std::istream& _in, BaseImporter& _bi, bool /*_swap if (!fh.is_valid()) ++complex_faces; break; - + case COLORRED: + if (prop.value == ValueTypeFLOAT32 || + prop.value == ValueTypeFLOAT) { + readValue(prop.value, _in, tmp); + c[0] = static_cast (tmp * 255.0f); + } else + readInteger(prop.value, _in, c[0]); + break; + case COLORGREEN: + if (prop.value == ValueTypeFLOAT32 || + prop.value == ValueTypeFLOAT) { + readValue(prop.value, _in, tmp); + c[1] = static_cast (tmp * 255.0f); + } else + readInteger(prop.value, _in, c[1]); + break; + case COLORBLUE: + if (prop.value == ValueTypeFLOAT32 || + prop.value == ValueTypeFLOAT) { + readValue(prop.value, _in, tmp); + c[2] = static_cast (tmp * 255.0f); + } else + readInteger(prop.value, _in, c[2]); + break; + case COLORALPHA: + if (prop.value == ValueTypeFLOAT32 || + prop.value == ValueTypeFLOAT) { + readValue(prop.value, _in, tmp); + c[3] = static_cast (tmp * 255.0f); + } else + readInteger(prop.value, _in, c[3]); + break; case CUSTOM_PROP: if (_opt.check(Options::Custom) && fh.is_valid()) readCustomProperty(_in, _bi, fh, prop.name, prop.value, prop.listIndexType); @@ -692,6 +750,8 @@ bool _PLYReader_::read_binary(std::istream& _in, BaseImporter& _bi, bool /*_swap break; } } + if (_opt.face_has_color()) + _bi.set_color(fh, Vec4uc(c)); } } else { @@ -741,6 +801,12 @@ void _PLYReader_::readValue(ValueType _type, std::istream& _in, float& _value) c restore(_in, tmp, options_.check(Options::MSB)); _value = tmp; break; + case ValueTypeDOUBLE: + case ValueTypeFLOAT64: + double dtmp; + readValue(_type, _in, dtmp); + _value = static_cast(dtmp); + break; default: _value = 0.0; std::cerr << "unsupported conversion type to float: " << _type << std::endl; @@ -905,9 +971,13 @@ void _PLYReader_::readValue(ValueType _type, std::istream& _in, int& _value) con //----------------------------------------------------------------------------- +template +void _PLYReader_::readInteger(ValueType _type, std::istream& _in, T& _value) const { -void _PLYReader_::readInteger(ValueType _type, std::istream& _in, int& _value) const { + static_assert(std::is_integral::value, "Integral required."); + int16_t tmp_int16_t; + uint16_t tmp_uint16_t; int32_t tmp_int32_t; uint32_t tmp_uint32_t; int8_t tmp_char; @@ -915,6 +985,22 @@ void _PLYReader_::readInteger(ValueType _type, std::istream& _in, int& _value) c switch (_type) { + case ValueTypeINT16: + + case ValueTypeSHORT: + restore(_in, tmp_int16_t, options_.check(Options::MSB)); + _value = tmp_int16_t; + + break; + + case ValueTypeUINT16: + + case ValueTypeUSHORT: + restore(_in, tmp_uint16_t, options_.check(Options::MSB)); + _value = tmp_uint16_t; + + break; + case ValueTypeINT: case ValueTypeINT32: @@ -954,71 +1040,12 @@ void _PLYReader_::readInteger(ValueType _type, std::istream& _in, int& _value) c default: _value = 0; - std::cerr << "unsupported conversion type to int: " << _type << std::endl; + std::cerr << "unsupported conversion type to integral: " << _type << std::endl; break; } } - -//----------------------------------------------------------------------------- - - -void _PLYReader_::readInteger(ValueType _type, std::istream& _in, unsigned int& _value) const { - - int32_t tmp_int32_t; - uint32_t tmp_uint32_t; - int8_t tmp_char; - uint8_t tmp_uchar; - - switch (_type) { - - case ValueTypeUINT: - - case ValueTypeUINT32: - - restore(_in, tmp_uint32_t, options_.check(Options::MSB)); - _value = tmp_uint32_t; - - break; - - case ValueTypeINT: - - case ValueTypeINT32: - - restore(_in, tmp_int32_t, options_.check(Options::MSB)); - _value = tmp_int32_t; - - break; - - case ValueTypeUCHAR: - - case ValueTypeUINT8: - - restore(_in, tmp_uchar, options_.check(Options::MSB)); - _value = tmp_uchar; - - break; - - case ValueTypeCHAR: - - case ValueTypeINT8: - - restore(_in, tmp_char, options_.check(Options::MSB)); - _value = tmp_char; - - break; - - default: - - _value = 0; - std::cerr << "unsupported conversion type to unsigned int: " << _type << std::endl; - - break; - } -} - - //------------------------------------------------------------------------------ @@ -1062,7 +1089,7 @@ std::string get_property_name(std::string _string1, std::string _string2) { //----------------------------------------------------------------------------- -_PLYReader_::ValueType get_property_type(std::string _string1, std::string _string2) { +_PLYReader_::ValueType get_property_type(std::string& _string1, std::string& _string2) { if (_string1 == "float32" || _string2 == "float32") @@ -1201,183 +1228,211 @@ bool _PLYReader_::can_u_read(std::istream& _is) const { _is >> keyword; while (keyword != "end_header") { - if (keyword == "comment") { - std::getline(_is, line); - } else if (keyword == "element") { - _is >> elementName; - _is >> elementCount; + if (keyword == "comment") { + std::getline(_is, line); + } else if (keyword == "element") { + _is >> elementName; + _is >> elementCount; - ElementInfo element; - element.name_ = elementName; - element.count_ = elementCount; + ElementInfo element; + element.name_ = elementName; + element.count_ = elementCount; - if (elementName == "vertex") { - vertexCount_ = elementCount; - element.element_ = VERTEX; - } else if (elementName == "face") { - faceCount_ = elementCount; - element.element_ = FACE; - } else { - omerr() << "PLY header unsupported element type: " << elementName << std::endl; - element.element_ = UNKNOWN; - } + if (elementName == "vertex") { + vertexCount_ = elementCount; + element.element_ = VERTEX; + } else if (elementName == "face") { + faceCount_ = elementCount; + element.element_ = FACE; + } else { + omerr() << "PLY header unsupported element type: " << elementName << std::endl; + element.element_ = UNKNOWN; + } - elements_.push_back(element); - } else if (keyword == "property") { - std::string tmp1; - std::string tmp2; + elements_.push_back(element); + } else if (keyword == "property") { + std::string tmp1; + std::string tmp2; - // Read first keyword, as it might be a list - _is >> tmp1; + // Read first keyword, as it might be a list + _is >> tmp1; - if (tmp1 == "list") { - _is >> listIndexType; - _is >> listEntryType; - _is >> propertyName; + if (tmp1 == "list") { + _is >> listIndexType; + _is >> listEntryType; + _is >> propertyName; - ValueType indexType = Unsupported; - ValueType entryType = Unsupported; + ValueType indexType = Unsupported; + ValueType entryType = Unsupported; - if (listIndexType == "uint8") { - indexType = ValueTypeUINT8; - } else if (listIndexType == "uchar") { - indexType = ValueTypeUCHAR; - } else if (listIndexType == "int") { - indexType = ValueTypeINT; - } else { - omerr() << "Unsupported Index type for property list: " << listIndexType << std::endl; - continue; - } + if (listIndexType == "uint8") { + indexType = ValueTypeUINT8; + } else if (listIndexType == "uint16") { + indexType = ValueTypeUINT16; + } else if (listIndexType == "uchar") { + indexType = ValueTypeUCHAR; + } else if (listIndexType == "int") { + indexType = ValueTypeINT; + } else { + omerr() << "Unsupported Index type for property list: " << listIndexType << std::endl; + return false; + } - entryType = get_property_type(listEntryType, listEntryType); + entryType = get_property_type(listEntryType, listEntryType); - if (entryType == Unsupported) { - omerr() << "Unsupported Entry type for property list: " << listEntryType << std::endl; - } + if (entryType == Unsupported) { + omerr() << "Unsupported Entry type for property list: " << listEntryType << std::endl; + } - PropertyInfo property(CUSTOM_PROP, entryType, propertyName); - property.listIndexType = indexType; + PropertyInfo property(CUSTOM_PROP, entryType, propertyName); + property.listIndexType = indexType; - if (elementName == "face") - { - // special case for vertex indices - if (propertyName == "vertex_index" || propertyName == "vertex_indices") - { - property.property = VERTEX_INDICES; - - if (!elements_.back().properties_.empty()) - { - omerr() << "Custom face Properties defined, before 'vertex_indices' property was defined. They will be skipped" << std::endl; - elements_.back().properties_.clear(); - } - } + if (elementName == "face") + { + // special case for vertex indices + if (propertyName == "vertex_index" || propertyName == "vertex_indices") + { + property.property = VERTEX_INDICES; - } - else - omerr() << "property " << propertyName << " belongs to unsupported element " << elementName << std::endl; - - elements_.back().properties_.push_back(property); - - } else { - // as this is not a list property, read second value of property - _is >> tmp2; - - - // Extract name and type of property - // As the order seems to be different in some files, autodetect it. - ValueType valueType = get_property_type(tmp1, tmp2); - propertyName = get_property_name(tmp1, tmp2); - - PropertyInfo entry; - - //special treatment for some vertex properties. - if (elementName == "vertex") { - if (propertyName == "x") { - entry = PropertyInfo(XCOORD, valueType); - vertexDimension_++; - } else if (propertyName == "y") { - entry = PropertyInfo(YCOORD, valueType); - vertexDimension_++; - } else if (propertyName == "z") { - entry = PropertyInfo(ZCOORD, valueType); - vertexDimension_++; - } else if (propertyName == "nx") { - entry = PropertyInfo(XNORM, valueType); - options_ += Options::VertexNormal; - } else if (propertyName == "ny") { - entry = PropertyInfo(YNORM, valueType); - options_ += Options::VertexNormal; - } else if (propertyName == "nz") { - entry = PropertyInfo(ZNORM, valueType); - options_ += Options::VertexNormal; - } else if (propertyName == "u" || propertyName == "s") { - entry = PropertyInfo(TEXX, valueType); - options_ += Options::VertexTexCoord; - } else if (propertyName == "v" || propertyName == "t") { - entry = PropertyInfo(TEXY, valueType); - options_ += Options::VertexTexCoord; - } else if (propertyName == "red") { - entry = PropertyInfo(COLORRED, valueType); - options_ += Options::VertexColor; - if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32) - options_ += Options::ColorFloat; - } else if (propertyName == "green") { - entry = PropertyInfo(COLORGREEN, valueType); - options_ += Options::VertexColor; - if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32) - options_ += Options::ColorFloat; - } else if (propertyName == "blue") { - entry = PropertyInfo(COLORBLUE, valueType); - options_ += Options::VertexColor; - if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32) - options_ += Options::ColorFloat; - } else if (propertyName == "diffuse_red") { - entry = PropertyInfo(COLORRED, valueType); - options_ += Options::VertexColor; - if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32) - options_ += Options::ColorFloat; - } else if (propertyName == "diffuse_green") { - entry = PropertyInfo(COLORGREEN, valueType); - options_ += Options::VertexColor; - if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32) - options_ += Options::ColorFloat; - } else if (propertyName == "diffuse_blue") { - entry = PropertyInfo(COLORBLUE, valueType); - options_ += Options::VertexColor; - if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32) - options_ += Options::ColorFloat; - } else if (propertyName == "alpha") { - entry = PropertyInfo(COLORALPHA, valueType); - options_ += Options::VertexColor; - options_ += Options::ColorAlpha; - if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32) - options_ += Options::ColorFloat; - } - } - - //not a special property, load as custom - if (entry.value == Unsupported){ - Property prop = CUSTOM_PROP; - options_ += Options::Custom; - entry = PropertyInfo(prop, valueType, propertyName); - } - - if (entry.property != UNSUPPORTED) + if (!elements_.back().properties_.empty()) { - elements_.back().properties_.push_back(entry); + omerr() << "Custom face Properties defined, before 'vertex_indices' property was defined. They will be skipped" << std::endl; + elements_.back().properties_.clear(); } + } else { + options_ += Options::Custom; } + } + else + omerr() << "property " << propertyName << " belongs to unsupported element " << elementName << std::endl; + + elements_.back().properties_.push_back(property); + } else { - omlog() << "Unsupported keyword : " << keyword << std::endl; + // as this is not a list property, read second value of property + _is >> tmp2; + + + // Extract name and type of property + // As the order seems to be different in some files, autodetect it. + ValueType valueType = get_property_type(tmp1, tmp2); + propertyName = get_property_name(tmp1, tmp2); + + PropertyInfo entry; + + //special treatment for some vertex properties. + if (elementName == "vertex") { + if (propertyName == "x") { + entry = PropertyInfo(XCOORD, valueType); + vertexDimension_++; + } else if (propertyName == "y") { + entry = PropertyInfo(YCOORD, valueType); + vertexDimension_++; + } else if (propertyName == "z") { + entry = PropertyInfo(ZCOORD, valueType); + vertexDimension_++; + } else if (propertyName == "nx") { + entry = PropertyInfo(XNORM, valueType); + options_ += Options::VertexNormal; + } else if (propertyName == "ny") { + entry = PropertyInfo(YNORM, valueType); + options_ += Options::VertexNormal; + } else if (propertyName == "nz") { + entry = PropertyInfo(ZNORM, valueType); + options_ += Options::VertexNormal; + } else if (propertyName == "u" || propertyName == "s") { + entry = PropertyInfo(TEXX, valueType); + options_ += Options::VertexTexCoord; + } else if (propertyName == "v" || propertyName == "t") { + entry = PropertyInfo(TEXY, valueType); + options_ += Options::VertexTexCoord; + } else if (propertyName == "red") { + entry = PropertyInfo(COLORRED, valueType); + options_ += Options::VertexColor; + if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32) + options_ += Options::ColorFloat; + } else if (propertyName == "green") { + entry = PropertyInfo(COLORGREEN, valueType); + options_ += Options::VertexColor; + if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32) + options_ += Options::ColorFloat; + } else if (propertyName == "blue") { + entry = PropertyInfo(COLORBLUE, valueType); + options_ += Options::VertexColor; + if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32) + options_ += Options::ColorFloat; + } else if (propertyName == "diffuse_red") { + entry = PropertyInfo(COLORRED, valueType); + options_ += Options::VertexColor; + if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32) + options_ += Options::ColorFloat; + } else if (propertyName == "diffuse_green") { + entry = PropertyInfo(COLORGREEN, valueType); + options_ += Options::VertexColor; + if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32) + options_ += Options::ColorFloat; + } else if (propertyName == "diffuse_blue") { + entry = PropertyInfo(COLORBLUE, valueType); + options_ += Options::VertexColor; + if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32) + options_ += Options::ColorFloat; + } else if (propertyName == "alpha") { + entry = PropertyInfo(COLORALPHA, valueType); + options_ += Options::VertexColor; + options_ += Options::ColorAlpha; + if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32) + options_ += Options::ColorFloat; + } + } + else if (elementName == "face") { + if (propertyName == "red") { + entry = PropertyInfo(COLORRED, valueType); + options_ += Options::FaceColor; + if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32) + options_ += Options::ColorFloat; + } else if (propertyName == "green") { + entry = PropertyInfo(COLORGREEN, valueType); + options_ += Options::FaceColor; + if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32) + options_ += Options::ColorFloat; + } else if (propertyName == "blue") { + entry = PropertyInfo(COLORBLUE, valueType); + options_ += Options::FaceColor; + if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32) + options_ += Options::ColorFloat; + } else if (propertyName == "alpha") { + entry = PropertyInfo(COLORALPHA, valueType); + options_ += Options::FaceColor; + options_ += Options::ColorAlpha; + if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32) + options_ += Options::ColorFloat; + } + } + + //not a special property, load as custom + if (entry.value == Unsupported){ + Property prop = CUSTOM_PROP; + options_ += Options::Custom; + entry = PropertyInfo(prop, valueType, propertyName); + } + + if (entry.property != UNSUPPORTED) + { + elements_.back().properties_.push_back(entry); + } } - streamPos = _is.tellg(); - _is >> keyword; - if (_is.bad()) { - omerr() << "Error while reading PLY file header" << std::endl; - return false; - } + } else { + omlog() << "Unsupported keyword : " << keyword << std::endl; + } + + streamPos = _is.tellg(); + _is >> keyword; + if (_is.bad()) { + omerr() << "Error while reading PLY file header" << std::endl; + return false; + } } // As the binary data is directy after the end_header keyword diff --git a/src/OpenMesh/Core/IO/reader/PLYReader.hh b/src/OpenMesh/Core/IO/reader/PLYReader.hh index c887a5bf..44ba7a06 100644 --- a/src/OpenMesh/Core/IO/reader/PLYReader.hh +++ b/src/OpenMesh/Core/IO/reader/PLYReader.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= @@ -102,19 +97,19 @@ public: _PLYReader_(); - std::string get_description() const { return "PLY polygon file format"; } - std::string get_extensions() const { return "ply"; } - std::string get_magic() const { return "PLY"; } + std::string get_description() const override { return "PLY polygon file format"; } + std::string get_extensions() const override { return "ply"; } + std::string get_magic() const override { return "PLY"; } bool read(const std::string& _filename, BaseImporter& _bi, - Options& _opt); + Options& _opt) override; bool read(std::istream& _is, BaseImporter& _bi, - Options& _opt); + Options& _opt) override; - bool can_u_read(const std::string& _filename) const; + bool can_u_read(const std::string& _filename) const override; enum ValueType { Unsupported, @@ -135,8 +130,6 @@ private: bool read_ascii(std::istream& _in, BaseImporter& _bi, const Options& _opt) const; bool read_binary(std::istream& _in, BaseImporter& _bi, bool swap, const Options& _opt) const; - float readToFloatValue(ValueType _type , std::fstream& _in) const; - void readValue(ValueType _type , std::istream& _in, float& _value) const; void readValue(ValueType _type , std::istream& _in, double& _value) const; void readValue(ValueType _type , std::istream& _in, unsigned int& _value) const; @@ -146,8 +139,8 @@ private: void readValue(ValueType _type , std::istream& _in, short& _value) const; void readValue(ValueType _type , std::istream& _in, signed char& _value) const; - void readInteger(ValueType _type, std::istream& _in, int& _value) const; - void readInteger(ValueType _type, std::istream& _in, unsigned int& _value) const; + template + void readInteger(ValueType _type, std::istream& _in, T& _value) const; /// Read unsupported properties in PLY file void consume_input(std::istream& _in, int _count) const { @@ -219,6 +212,18 @@ private: _in >> _value; } + template + inline void readInteger(_PLYReader_::ValueType _type, std::istream& _in, T& _value, OpenMesh::GenProg::TrueType /*_binary*/) const + { + readInteger(_type, _in, _value); + } + + template + inline void readInteger(_PLYReader_::ValueType _type, std::istream& _in, T& _value, OpenMesh::GenProg::FalseType /*_binary*/) const + { + _in >> _value; + } + //read and assign custom properties with the given type. Also creates property, if not exist template void readCreateCustomProperty(std::istream& _in, BaseImporter& _bi, Handle _h, const std::string& _propName, const ValueType _valueType, const ValueType _listType) const; diff --git a/src/OpenMesh/Core/IO/reader/STLReader.cc b/src/OpenMesh/Core/IO/reader/STLReader.cc index 6dd8569b..c5a12917 100644 --- a/src/OpenMesh/Core/IO/reader/STLReader.cc +++ b/src/OpenMesh/Core/IO/reader/STLReader.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //== INCLUDES ================================================================= @@ -176,7 +171,7 @@ class CmpVec { public: - CmpVec(float _eps=FLT_MIN) : eps_(_eps) {} + explicit CmpVec(float _eps=FLT_MIN) : eps_(_eps) {} bool operator()( const Vec3f& _v0, const Vec3f& _v1 ) const { diff --git a/src/OpenMesh/Core/IO/reader/STLReader.hh b/src/OpenMesh/Core/IO/reader/STLReader.hh index b6426236..ff094d0f 100644 --- a/src/OpenMesh/Core/IO/reader/STLReader.hh +++ b/src/OpenMesh/Core/IO/reader/STLReader.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= @@ -97,17 +92,17 @@ public: virtual ~_STLReader_() {}; - std::string get_description() const + std::string get_description() const override { return "Stereolithography Interface Format"; } - std::string get_extensions() const { return "stl stla stlb"; } + std::string get_extensions() const override { return "stl stla stlb"; } bool read(const std::string& _filename, BaseImporter& _bi, - Options& _opt); + Options& _opt) override; bool read(std::istream& _in, BaseImporter& _bi, - Options& _opt); + Options& _opt) override; /** Set the threshold to be used for considering two point to be equal. Can be used to merge small gaps */ diff --git a/src/OpenMesh/Core/IO/writer/BaseWriter.cc b/src/OpenMesh/Core/IO/writer/BaseWriter.cc index 7b7f29b6..5b959093 100644 --- a/src/OpenMesh/Core/IO/writer/BaseWriter.cc +++ b/src/OpenMesh/Core/IO/writer/BaseWriter.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //=== INCLUDES ================================================================ diff --git a/src/OpenMesh/Core/IO/writer/BaseWriter.hh b/src/OpenMesh/Core/IO/writer/BaseWriter.hh index 3e1688f0..fb1c1962 100644 --- a/src/OpenMesh/Core/IO/writer/BaseWriter.hh +++ b/src/OpenMesh/Core/IO/writer/BaseWriter.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= @@ -138,11 +133,13 @@ protected: bool check(BaseExporter& _be, Options _opt) const { - return (_opt.check(Options::VertexNormal ) <= _be.has_vertex_normals()) - && (_opt.check(Options::VertexTexCoord)<= _be.has_vertex_texcoords()) - && (_opt.check(Options::VertexColor) <= _be.has_vertex_colors()) - && (_opt.check(Options::FaceNormal) <= _be.has_face_normals()) - && (_opt.check(Options::FaceColor) <= _be.has_face_colors()); + // Check for all Options. When we want to write them (_opt.check() ) , they have to be available ( has_ ) + // Converts to not A (write them) or B (available) + return ( !_opt.check(Options::VertexNormal ) || _be.has_vertex_normals()) + && ( !_opt.check(Options::VertexTexCoord)|| _be.has_vertex_texcoords()) + && ( !_opt.check(Options::VertexColor) || _be.has_vertex_colors()) + && ( !_opt.check(Options::FaceNormal) || _be.has_face_normals()) + && ( !_opt.check(Options::FaceColor) || _be.has_face_colors()); } }; diff --git a/src/OpenMesh/Core/IO/writer/OBJWriter.cc b/src/OpenMesh/Core/IO/writer/OBJWriter.cc index a592e0da..681fbfb1 100644 --- a/src/OpenMesh/Core/IO/writer/OBJWriter.cc +++ b/src/OpenMesh/Core/IO/writer/OBJWriter.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //== INCLUDES ================================================================= @@ -97,28 +92,32 @@ write(const std::string& _filename, BaseExporter& _be, Options _opt, std::stream return false; } + // Set precision on output stream. The default is set via IOManager and passed through to all writers. out.precision(_precision); + // Set fixed output to avoid problems with programs not reading scientific notation correctly + out << std::fixed; + { #if defined(WIN32) - std::string::size_type dot = _filename.find_last_of("\\/"); + std::string::size_type dotposition = _filename.find_last_of("\\/"); #else - std::string::size_type dot = _filename.rfind("/"); + std::string::size_type dotposition = _filename.rfind("/"); #endif - if (dot == std::string::npos){ + if (dotposition == std::string::npos){ path_ = "./"; objName_ = _filename; }else{ - path_ = _filename.substr(0,dot+1); - objName_ = _filename.substr(dot+1); + path_ = _filename.substr(0,dotposition+1); + objName_ = _filename.substr(dotposition+1); } //remove the file extension - dot = objName_.find_last_of("."); + dotposition = objName_.find_last_of("."); - if(dot != std::string::npos) - objName_ = objName_.substr(0,dot); + if(dotposition != std::string::npos) + objName_ = objName_.substr(0,dotposition); } bool result = write(out, _be, _opt, _precision); @@ -207,7 +206,6 @@ _OBJWriter_:: write(std::ostream& _out, BaseExporter& _be, Options _opt, std::streamsize _precision) const { unsigned int idx; - size_t i, j,nV, nF; Vec3f v, n; Vec2f t; VertexHandle vh; @@ -274,9 +272,9 @@ write(std::ostream& _out, BaseExporter& _be, Options _opt, std::streamsize _prec std::vector texCoords; //add all texCoords to map unsigned int num = _be.get_face_texcoords(texCoords); - for(unsigned int i = 0; i < num ; ++i) + for(size_t i = 0; i < num ; ++i) { - texMap[texCoords[i]] = i; + texMap[texCoords[i]] = static_cast(i); } } @@ -304,7 +302,7 @@ write(std::ostream& _out, BaseExporter& _be, Options _opt, std::streamsize _prec } // vertex data (point, normals, texcoords) - for (i=0, nV=_be.n_vertices(); i struct Enabler { - Enabler( T& obj ) : obj_(obj) + explicit Enabler( T& obj ) : obj_(obj) {} ~Enabler() { obj_.enable(); } @@ -182,13 +177,13 @@ bool _OMWriter_::write_binary(std::ostream& _os, BaseExporter& _be, size_t bytes = 0; - bool swap = _opt.check(Options::Swap) || (Endian::local() == Endian::MSB); + const bool swap = + _opt.check(Options::Swap) || (Endian::local() == Endian::MSB); unsigned int i, nV, nF; Vec3f v; + Vec3d vd; Vec2f t; - std::vector vhandles; - // -------------------- write header OMFormat::Header header; @@ -218,14 +213,28 @@ bool _OMWriter_::write_binary(std::ostream& _os, BaseExporter& _be, chunk_header.name_ = false; chunk_header.entity_ = OMFormat::Chunk::Entity_Vertex; chunk_header.type_ = OMFormat::Chunk::Type_Pos; - chunk_header.signed_ = OMFormat::is_signed(v[0]); - chunk_header.float_ = OMFormat::is_float(v[0]); - chunk_header.dim_ = OMFormat::dim(v); - chunk_header.bits_ = OMFormat::bits(v[0]); + if (_be.is_point_double()) + { + chunk_header.signed_ = OMFormat::is_signed(vd[0]); + chunk_header.float_ = OMFormat::is_float(vd[0]); + chunk_header.dim_ = OMFormat::dim(vd); + chunk_header.bits_ = OMFormat::bits(vd[0]); + } + else + { + chunk_header.signed_ = OMFormat::is_signed(v[0]); + chunk_header.float_ = OMFormat::is_float(v[0]); + chunk_header.dim_ = OMFormat::dim(v); + chunk_header.bits_ = OMFormat::bits(v[0]); + } bytes += store( _os, chunk_header, swap ); - for (i=0, nV=header.n_vertices_; i(i))); + auto to_vertex_id = _be.get_to_vertex_id(HalfedgeHandle(static_cast(i))); + auto face_id = _be.get_face_id(HalfedgeHandle(static_cast(i))); + + bytes += store( _os, next_id, OMFormat::Chunk::Integer_Size(chunk_header.bits_), swap ); + bytes += store( _os, to_vertex_id, OMFormat::Chunk::Integer_Size(chunk_header.bits_), swap ); + bytes += store( _os, face_id, OMFormat::Chunk::Integer_Size(chunk_header.bits_), swap ); + } + } + + // ---------- write vertex topology (outgoing halfedge) + if (_be.n_vertices()) + { + chunk_header.reserved_ = 0; + chunk_header.name_ = false; + chunk_header.entity_ = OMFormat::Chunk::Entity_Vertex; + chunk_header.type_ = OMFormat::Chunk::Type_Topology; + chunk_header.signed_ = true; + chunk_header.float_ = true; // TODO: is this correct? This causes a scalar size of 1 in OMFormat.hh scalar_size which we need I think? + chunk_header.dim_ = OMFormat::Chunk::Dim_1D; + chunk_header.bits_ = OMFormat::needed_bits(_be.n_edges()*4); // *2 due to halfedge ids being stored, *2 due to signedness + + bytes += store( _os, chunk_header, swap ); + for (i=0, nV=header.n_vertices_; istore(_os, swap ); } @@ -384,51 +461,112 @@ bool _OMWriter_::write_binary(std::ostream& _os, BaseExporter& _be, #endif } + // ---------- write vertex status + if (_be.n_vertices() && _be.has_vertex_status() && _opt.check(Options::Status)) + { + auto s = _be.status(VertexHandle(0)); + chunk_header.name_ = false; + chunk_header.entity_ = OMFormat::Chunk::Entity_Vertex; + chunk_header.type_ = OMFormat::Chunk::Type_Status; + chunk_header.signed_ = false; + chunk_header.float_ = false; + chunk_header.dim_ = OMFormat::Chunk::Dim_1D; + chunk_header.bits_ = OMFormat::bits(s); + + // std::clog << chunk_header << std::endl; + bytes += store(_os, chunk_header, swap); + + for (i = 0, nV = header.n_vertices_; i < nV; ++i) + bytes += store(_os, _be.status(VertexHandle(i)), swap); + } + + // ---------- write edge status + if (_be.n_edges() && _be.has_edge_status() && _opt.check(Options::Status)) + { + auto s = _be.status(EdgeHandle(0)); + chunk_header.name_ = false; + chunk_header.entity_ = OMFormat::Chunk::Entity_Edge; + chunk_header.type_ = OMFormat::Chunk::Type_Status; + chunk_header.signed_ = false; + chunk_header.float_ = false; + chunk_header.dim_ = OMFormat::Chunk::Dim_1D; + chunk_header.bits_ = OMFormat::bits(s); + + // std::clog << chunk_header << std::endl; + bytes += store(_os, chunk_header, swap); + + for (i = 0, nV = header.n_edges_; i < nV; ++i) + bytes += store(_os, _be.status(EdgeHandle(i)), swap); + } + + // ---------- write halfedge status + if (_be.n_edges() && _be.has_halfedge_status() && _opt.check(Options::Status)) + { + auto s = _be.status(HalfedgeHandle(0)); + chunk_header.name_ = false; + chunk_header.entity_ = OMFormat::Chunk::Entity_Halfedge; + chunk_header.type_ = OMFormat::Chunk::Type_Status; + chunk_header.signed_ = false; + chunk_header.float_ = false; + chunk_header.dim_ = OMFormat::Chunk::Dim_1D; + chunk_header.bits_ = OMFormat::bits(s); + + // std::clog << chunk_header << std::endl; + bytes += store(_os, chunk_header, swap); + + for (i = 0, nV = header.n_edges_ * 2; i < nV; ++i) + bytes += store(_os, _be.status(HalfedgeHandle(i)), swap); + } + + // ---------- write face status + if (_be.n_faces() && _be.has_face_status() && _opt.check(Options::Status)) + { + auto s = _be.status(FaceHandle(0)); + chunk_header.name_ = false; + chunk_header.entity_ = OMFormat::Chunk::Entity_Face; + chunk_header.type_ = OMFormat::Chunk::Type_Status; + chunk_header.signed_ = false; + chunk_header.float_ = false; + chunk_header.dim_ = OMFormat::Chunk::Dim_1D; + chunk_header.bits_ = OMFormat::bits(s); + + // std::clog << chunk_header << std::endl; + bytes += store(_os, chunk_header, swap); + + for (i = 0, nV = header.n_faces_; i < nV; ++i) + bytes += store(_os, _be.status(FaceHandle(i)), swap); + } + // -------------------- write custom properties - BaseKernel::const_prop_iterator prop; - for (prop = _be.kernel()->vprops_begin(); - prop != _be.kernel()->vprops_end(); ++prop) + const auto store_property = [this, &_os, swap, &bytes]( + const BaseKernel::const_prop_iterator _it_begin, + const BaseKernel::const_prop_iterator _it_end, + const OMFormat::Chunk::Entity _ent) { - if ( !*prop ) continue; - if ( (*prop)->name()[1]==':') continue; - bytes += store_binary_custom_chunk(_os, **prop, - OMFormat::Chunk::Entity_Vertex, swap ); - } - for (prop = _be.kernel()->fprops_begin(); - prop != _be.kernel()->fprops_end(); ++prop) - { - if ( !*prop ) continue; - if ( (*prop)->name()[1]==':') continue; - bytes += store_binary_custom_chunk(_os, **prop, - OMFormat::Chunk::Entity_Face, swap ); - } - for (prop = _be.kernel()->eprops_begin(); - prop != _be.kernel()->eprops_end(); ++prop) - { - if ( !*prop ) continue; - if ( (*prop)->name()[1]==':') continue; - bytes += store_binary_custom_chunk(_os, **prop, - OMFormat::Chunk::Entity_Edge, swap ); - } - for (prop = _be.kernel()->hprops_begin(); - prop != _be.kernel()->hprops_end(); ++prop) - { - if ( !*prop ) continue; - if ( (*prop)->name()[1]==':') continue; - bytes += store_binary_custom_chunk(_os, **prop, - OMFormat::Chunk::Entity_Halfedge, swap ); - } - for (prop = _be.kernel()->mprops_begin(); - prop != _be.kernel()->mprops_end(); ++prop) - { - if ( !*prop ) continue; - if ( (*prop)->name()[1]==':') continue; - bytes += store_binary_custom_chunk(_os, **prop, - OMFormat::Chunk::Entity_Mesh, swap ); - } + for (auto prop = _it_begin; prop != _it_end; ++prop) + { + if (!*prop || (*prop)->name().empty() || + ((*prop)->name().size() > 1 && (*prop)->name()[1] == ':')) + { // skip dead and "private" properties (no name or name matches "?:*") + continue; + } + bytes += store_binary_custom_chunk(_os, **prop, _ent, swap); + } + }; + + store_property(_be.kernel()->vprops_begin(), _be.kernel()->vprops_end(), + OMFormat::Chunk::Entity_Vertex); + store_property(_be.kernel()->fprops_begin(), _be.kernel()->fprops_end(), + OMFormat::Chunk::Entity_Face); + store_property(_be.kernel()->eprops_begin(), _be.kernel()->eprops_end(), + OMFormat::Chunk::Entity_Edge); + store_property(_be.kernel()->hprops_begin(), _be.kernel()->hprops_end(), + OMFormat::Chunk::Entity_Halfedge); + store_property(_be.kernel()->mprops_begin(), _be.kernel()->mprops_end(), + OMFormat::Chunk::Entity_Mesh); memset(&chunk_header, 0, sizeof(chunk_header)); chunk_header.name_ = false; diff --git a/src/OpenMesh/Core/IO/writer/OMWriter.hh b/src/OpenMesh/Core/IO/writer/OMWriter.hh index efc48a8c..9693951d 100644 --- a/src/OpenMesh/Core/IO/writer/OMWriter.hh +++ b/src/OpenMesh/Core/IO/writer/OMWriter.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= @@ -103,17 +98,17 @@ public: /// Destructor virtual ~_OMWriter_() {}; - std::string get_description() const + std::string get_description() const override { return "OpenMesh Format"; } - std::string get_extensions() const + std::string get_extensions() const override { return "om"; } - bool write(std::ostream&, BaseExporter&, Options, std::streamsize _precision = 6) const; + bool write(std::ostream&, BaseExporter&, Options, std::streamsize _precision = 6) const override; + size_t binary_size(BaseExporter& _be, Options _opt) const override; - - size_t binary_size(BaseExporter& _be, Options _opt) const; + static OMFormat::uint8 get_version() { return version_; } protected: @@ -121,7 +116,7 @@ protected: static const OMFormat::uchar magic_[3]; static const OMFormat::uint8 version_; - bool write(const std::string&, BaseExporter&, Options, std::streamsize _precision = 6) const; + bool write(const std::string&, BaseExporter&, Options, std::streamsize _precision = 6) const override; bool write_binary(std::ostream&, BaseExporter&, Options) const; diff --git a/src/OpenMesh/Core/IO/writer/PLYWriter.cc b/src/OpenMesh/Core/IO/writer/PLYWriter.cc index 0314b5a8..49db3ec6 100644 --- a/src/OpenMesh/Core/IO/writer/PLYWriter.cc +++ b/src/OpenMesh/Core/IO/writer/PLYWriter.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //== INCLUDES ================================================================= @@ -127,14 +122,6 @@ write(std::ostream& _os, BaseExporter& _be, Options _opt, std::streamsize _preci omerr() << "[PLYWriter] : Warning: Face normals are not supported and thus not exported! " << std::endl; } - if ( _opt.check(Options::FaceColor) ) { - // Face normals are not supported - // Uncheck these options and output message that - // they are not written out even though they were requested - _opt.unset(Options::FaceColor); - omerr() << "[PLYWriter] : Warning: Face colors are not supported and thus not exported! " << std::endl; - } - options_ = _opt; @@ -318,6 +305,24 @@ void _PLYWriter_::write_header(std::ostream& _out, BaseExporter& _be, Options& _ _out << "element face " << _be.n_faces() << '\n'; _out << "property list uchar int vertex_indices" << '\n'; + if ( _opt.face_has_color() ){ + if ( _opt.color_is_float() ) { + _out << "property float red" << '\n'; + _out << "property float green" << '\n'; + _out << "property float blue" << '\n'; + + if ( _opt.color_has_alpha() ) + _out << "property float alpha" << '\n'; + } else { + _out << "property uchar red" << '\n'; + _out << "property uchar green" << '\n'; + _out << "property uchar blue" << '\n'; + + if ( _opt.color_has_alpha() ) + _out << "property uchar alpha" << '\n'; + } + } + _ofProps = writeCustomTypeHeader(_out, _be.kernel()->fprops_begin(), _be.kernel()->fprops_end()); _out << "end_header" << '\n'; @@ -340,6 +345,7 @@ write_ascii(std::ostream& _out, BaseExporter& _be, Options _opt) const OpenMesh::Vec4f cAf; OpenMesh::Vec2f t; VertexHandle vh; + FaceHandle fh; std::vector vhandles; std::vector vProps; @@ -405,12 +411,37 @@ write_ascii(std::ostream& _out, BaseExporter& _be, Options _opt) const // faces (indices starting at 0) for (i=0, nF=int(_be.n_faces()); i::iterator iter = fProps.begin(); iter < fProps.end(); ++iter) write_customProp(_out,*iter,i); @@ -567,6 +598,7 @@ write_binary(std::ostream& _out, BaseExporter& _be, Options _opt) const OpenMesh::Vec4uc c; OpenMesh::Vec4f cf; VertexHandle vh; + FaceHandle fh; std::vector vhandles; // vProps and fProps will be empty, until custom properties are supported by the binary writer @@ -629,12 +661,35 @@ write_binary(std::ostream& _out, BaseExporter& _be, Options _opt) const for (i=0, nF=int(_be.n_faces()); i::iterator iter = fProps.begin(); iter < fProps.end(); ++iter) write_customProp(_out,*iter,i); } diff --git a/src/OpenMesh/Core/IO/writer/PLYWriter.hh b/src/OpenMesh/Core/IO/writer/PLYWriter.hh index 65addb66..08814955 100644 --- a/src/OpenMesh/Core/IO/writer/PLYWriter.hh +++ b/src/OpenMesh/Core/IO/writer/PLYWriter.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= @@ -87,6 +82,7 @@ namespace IO { currently supported options: - VertexColors + - FaceColors - Binary - Binary -> MSB */ @@ -99,14 +95,14 @@ public: /// Destructor virtual ~_PLYWriter_() {}; - std::string get_description() const { return "PLY polygon file format"; } - std::string get_extensions() const { return "ply"; } + std::string get_description() const override { return "PLY polygon file format"; } + std::string get_extensions() const override { return "ply"; } - bool write(const std::string&, BaseExporter&, Options, std::streamsize _precision = 6) const; + bool write(const std::string&, BaseExporter&, Options, std::streamsize _precision = 6) const override; - bool write(std::ostream&, BaseExporter&, Options, std::streamsize _precision = 6) const; + bool write(std::ostream&, BaseExporter&, Options, std::streamsize _precision = 6) const override; - size_t binary_size(BaseExporter& _be, Options _opt) const; + size_t binary_size(BaseExporter& _be, Options _opt) const override; enum ValueType { Unsupported = 0, @@ -124,7 +120,7 @@ private: { ValueType type; const BaseProperty* property; - CustomProperty(const BaseProperty* const _p):type(Unsupported),property(_p){} + explicit CustomProperty(const BaseProperty* const _p):type(Unsupported),property(_p){} }; const char* nameOfType_[12]; diff --git a/src/OpenMesh/Core/IO/writer/STLWriter.cc b/src/OpenMesh/Core/IO/writer/STLWriter.cc index 503fa03b..727eda55 100644 --- a/src/OpenMesh/Core/IO/writer/STLWriter.cc +++ b/src/OpenMesh/Core/IO/writer/STLWriter.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //== INCLUDES ================================================================= @@ -158,7 +153,7 @@ write_stla(const std::string& _filename, BaseExporter& _be, Options /* _opt */) - int i, nF(int(_be.n_faces())), nV; + int i, nF(int(_be.n_faces())); Vec3f a, b, c, n; std::vector vhandles; FaceHandle fh; @@ -172,7 +167,7 @@ write_stla(const std::string& _filename, BaseExporter& _be, Options /* _opt */) for (i=0; i vhandles; FaceHandle fh; @@ -226,7 +221,7 @@ write_stla(std::ostream& _out, BaseExporter& _be, Options /* _opt */, std::strea for (i=0; i vhandles; FaceHandle fh; @@ -294,7 +289,7 @@ write_stlb(const std::string& _filename, BaseExporter& _be, Options /* _opt */) for (i=0; i vhandles; FaceHandle fh; @@ -366,7 +361,7 @@ write_stlb(std::ostream& _out, BaseExporter& _be, Options /* _opt */, std::strea for (i=0; i diff --git a/src/OpenMesh/Core/Mesh/ArrayKernel.hh b/src/OpenMesh/Core/Mesh/ArrayKernel.hh index ccf2748c..bf68b8ca 100644 --- a/src/OpenMesh/Core/Mesh/ArrayKernel.hh +++ b/src/OpenMesh/Core/Mesh/ArrayKernel.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= @@ -345,10 +340,10 @@ public: void clean_keep_reservation(); // --- number of items --- - size_t n_vertices() const { return vertices_.size(); } - size_t n_halfedges() const { return 2*edges_.size(); } - size_t n_edges() const { return edges_.size(); } - size_t n_faces() const { return faces_.size(); } + size_t n_vertices() const override { return vertices_.size(); } + size_t n_halfedges() const override { return 2*edges_.size(); } + size_t n_edges() const override { return edges_.size(); } + size_t n_faces() const override { return faces_.size(); } bool vertices_empty() const { return vertices_.empty(); } bool halfedges_empty() const { return edges_.empty(); } @@ -702,7 +697,7 @@ public: typedef StatusSetT Base; public: - AutoStatusSetT(ArrayKernel& _kernel) + explicit AutoStatusSetT(ArrayKernel& _kernel) : StatusSetT(_kernel, _kernel.pop_bit_mask(Handle())) { /*assert(size() == 0);*/ } //the set should be empty on creation @@ -746,12 +741,12 @@ public: { handles_.reserve(_capacity_hint); } ~ExtStatusSetT() - { clear(); } + { Base::clear(); } // Complexity: O(1) inline void insert(Handle _hnd) { - if (!is_in(_hnd)) + if (!Base::is_in(_hnd)) { Base::insert(_hnd); handles_.push_back(_hnd); @@ -771,7 +766,8 @@ public: //! Complexity: O(1) inline void erase(iterator _it) { - assert(_it != end() && is_in(*_it)); + assert(_it != const_cast(this)->end() && + Base::is_in(*_it)); Base::erase(*_it); *_it = handles_.back(); _it.pop_back(); @@ -781,7 +777,7 @@ public: { for (iterator it = begin(); it != end(); ++it) { - assert(is_in(*it)); + assert(Base::is_in(*it)); Base::erase(*it); } handles_.clear(); @@ -908,7 +904,7 @@ private: //============================================================================= #if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_ARRAY_KERNEL_C) # define OPENMESH_ARRAY_KERNEL_TEMPLATES -# include "ArrayKernelT.cc" +# include "ArrayKernelT_impl.hh" #endif //============================================================================= #endif // OPENMESH_ARRAY_KERNEL_HH defined diff --git a/src/OpenMesh/Core/Mesh/ArrayKernelT.cc b/src/OpenMesh/Core/Mesh/ArrayKernelT_impl.hh similarity index 93% rename from src/OpenMesh/Core/Mesh/ArrayKernelT.cc rename to src/OpenMesh/Core/Mesh/ArrayKernelT_impl.hh index d38d093c..f62248ca 100644 --- a/src/OpenMesh/Core/Mesh/ArrayKernelT.cc +++ b/src/OpenMesh/Core/Mesh/ArrayKernelT_impl.hh @@ -39,13 +39,6 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision: 362 $ * - * $Date: 2011-01-26 10:21:12 +0100 (Mi, 26 Jan 2011) $ * - * * -\*===========================================================================*/ - #define OPENMESH_ARRAY_KERNEL_C //== INCLUDES ================================================================= diff --git a/src/OpenMesh/Core/Mesh/AttribKernelT.hh b/src/OpenMesh/Core/Mesh/AttribKernelT.hh index ca1e55ef..8dc1a2b8 100644 --- a/src/OpenMesh/Core/Mesh/AttribKernelT.hh +++ b/src/OpenMesh/Core/Mesh/AttribKernelT.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef OPENMESH_ATTRIBKERNEL_HH #define OPENMESH_ATTRIBKERNEL_HH @@ -110,10 +105,26 @@ public: FAttribs = MeshItems::FAttribs }; - typedef VPropHandleT DataVPropHandle; - typedef HPropHandleT DataHPropHandle; - typedef EPropHandleT DataEPropHandle; - typedef FPropHandleT DataFPropHandle; + typedef VPropHandleT DataVPropHandle; + typedef HPropHandleT DataHPropHandle; + typedef EPropHandleT DataEPropHandle; + typedef FPropHandleT DataFPropHandle; + + typedef VPropHandleT PointsPropertyHandle; + typedef VPropHandleT VertexNormalsPropertyHandle; + typedef VPropHandleT VertexColorsPropertyHandle; + typedef VPropHandleT VertexTexCoords1DPropertyHandle; + typedef VPropHandleT VertexTexCoords2DPropertyHandle; + typedef VPropHandleT VertexTexCoords3DPropertyHandle; + typedef HPropHandleT HalfedgeTexCoords1DPropertyHandle; + typedef HPropHandleT HalfedgeTexCoords2DPropertyHandle; + typedef HPropHandleT HalfedgeTexCoords3DPropertyHandle; + typedef EPropHandleT EdgeColorsPropertyHandle; + typedef HPropHandleT HalfedgeNormalsPropertyHandle; + typedef HPropHandleT HalfedgeColorsPropertyHandle; + typedef FPropHandleT FaceNormalsPropertyHandle; + typedef FPropHandleT FaceColorsPropertyHandle; + typedef FPropHandleT FaceTextureIndexPropertyHandle; public: @@ -245,6 +256,9 @@ public: void set_point(VertexHandle _vh, const Point& _p) { this->property(points_, _vh) = _p; } + const PointsPropertyHandle& points_property_handle() const + { return points_; } + //------------------------------------------------------------ vertex normals @@ -597,24 +611,6 @@ public: bool has_face_colors() const { return face_colors_.is_valid(); } bool has_face_texture_index() const { return face_texture_index_.is_valid(); } -public: - - typedef VPropHandleT PointsPropertyHandle; - typedef VPropHandleT VertexNormalsPropertyHandle; - typedef VPropHandleT VertexColorsPropertyHandle; - typedef VPropHandleT VertexTexCoords1DPropertyHandle; - typedef VPropHandleT VertexTexCoords2DPropertyHandle; - typedef VPropHandleT VertexTexCoords3DPropertyHandle; - typedef HPropHandleT HalfedgeTexCoords1DPropertyHandle; - typedef HPropHandleT HalfedgeTexCoords2DPropertyHandle; - typedef HPropHandleT HalfedgeTexCoords3DPropertyHandle; - typedef EPropHandleT EdgeColorsPropertyHandle; - typedef HPropHandleT HalfedgeNormalsPropertyHandle; - typedef HPropHandleT HalfedgeColorsPropertyHandle; - typedef FPropHandleT FaceNormalsPropertyHandle; - typedef FPropHandleT FaceColorsPropertyHandle; - typedef FPropHandleT FaceTextureIndexPropertyHandle; - public: //standard vertex properties PointsPropertyHandle points_pph() const @@ -744,48 +740,34 @@ private: { //mesh has no points? } - if(this->get_property_handle(vertex_normals_, - "v:normals")) - refcount_vnormals_ = 1; - if(this->get_property_handle(vertex_colors_, - "v:colors")) - refcount_vcolors_ = 1; - if(this->get_property_handle(vertex_texcoords1D_, - "v:texcoords1D")) - refcount_vtexcoords1D_ = 1; - if(this->get_property_handle(vertex_texcoords2D_, - "v:texcoords2D")) - refcount_vtexcoords2D_ = 1; - if(this->get_property_handle(vertex_texcoords3D_, - "v:texcoords3D")) - refcount_vtexcoords3D_ = 1; - if(this->get_property_handle(halfedge_texcoords1D_, - "h:texcoords1D")) - refcount_htexcoords1D_ = 1; - if(this->get_property_handle(halfedge_texcoords2D_, - "h:texcoords2D")) - refcount_htexcoords2D_ = 1; - if(this->get_property_handle(halfedge_texcoords3D_, - "h:texcoords3D")) - refcount_htexcoords3D_ = 1; - if(this->get_property_handle(halfedge_normals_, - "h:normals")) - refcount_henormals_ = 1; - if(this->get_property_handle(halfedge_colors_, - "h:colors")) - refcount_hecolors_ = 1; - if(this->get_property_handle(edge_colors_, - "e:colors")) - refcount_ecolors_ = 1; - if(this->get_property_handle(face_normals_, - "f:normals")) - refcount_fnormals_ = 1; - if(this->get_property_handle(face_colors_, - "f:colors")) - refcount_fcolors_ = 1; - if(this->get_property_handle(face_texture_index_, - "f:textureindex")) - refcount_ftextureIndex_ = 1; + refcount_vnormals_ = this->get_property_handle(vertex_normals_, + "v:normals") ? 1 : 0 ; + refcount_vcolors_ = this->get_property_handle(vertex_colors_, + "v:colors") ? 1 : 0 ; + refcount_vtexcoords1D_ = this->get_property_handle(vertex_texcoords1D_, + "v:texcoords1D") ? 1 : 0 ; + refcount_vtexcoords2D_ = this->get_property_handle(vertex_texcoords2D_, + "v:texcoords2D") ? 1 : 0 ; + refcount_vtexcoords3D_ = this->get_property_handle(vertex_texcoords3D_, + "v:texcoords3D") ? 1 : 0 ; + refcount_htexcoords1D_ = this->get_property_handle(halfedge_texcoords1D_, + "h:texcoords1D") ? 1 : 0 ; + refcount_htexcoords2D_ = this->get_property_handle(halfedge_texcoords2D_, + "h:texcoords2D") ? 1 : 0 ; + refcount_htexcoords3D_ = this->get_property_handle(halfedge_texcoords3D_, + "h:texcoords3D") ? 1 : 0 ; + refcount_henormals_ = this->get_property_handle(halfedge_normals_, + "h:normals") ? 1 : 0 ; + refcount_hecolors_ = this->get_property_handle(halfedge_colors_, + "h:colors") ? 1 : 0 ; + refcount_ecolors_ = this->get_property_handle(edge_colors_, + "e:colors") ? 1 : 0 ; + refcount_fnormals_ = this->get_property_handle(face_normals_, + "f:normals") ? 1 : 0 ; + refcount_fcolors_ = this->get_property_handle(face_colors_, + "f:colors") ? 1 : 0 ; + refcount_ftextureIndex_ = this->get_property_handle(face_texture_index_, + "f:textureindex") ? 1 : 0 ; } }; diff --git a/src/OpenMesh/Core/Mesh/Attributes.hh b/src/OpenMesh/Core/Mesh/Attributes.hh index e53f021a..e02066ce 100644 --- a/src/OpenMesh/Core/Mesh/Attributes.hh +++ b/src/OpenMesh/Core/Mesh/Attributes.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + /** diff --git a/src/OpenMesh/Core/Mesh/BaseKernel.cc b/src/OpenMesh/Core/Mesh/BaseKernel.cc index c0e174f3..1cdd9cf3 100644 --- a/src/OpenMesh/Core/Mesh/BaseKernel.cc +++ b/src/OpenMesh/Core/Mesh/BaseKernel.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #include #include @@ -69,27 +64,27 @@ void BaseKernel::property_stats(std::ostream& _ostr) const _ostr << vprops_.size() << " vprops:\n"; for (it=vps.begin(); it!=vps.end(); ++it) { - *it == NULL ? (void)(_ostr << "[deleted]" << "\n") : (*it)->stats(_ostr); + *it == nullptr ? (void)(_ostr << "[deleted]" << "\n") : (*it)->stats(_ostr); } _ostr << hprops_.size() << " hprops:\n"; for (it=hps.begin(); it!=hps.end(); ++it) { - *it == NULL ? (void)(_ostr << "[deleted]" << "\n") : (*it)->stats(_ostr); + *it == nullptr ? (void)(_ostr << "[deleted]" << "\n") : (*it)->stats(_ostr); } _ostr << eprops_.size() << " eprops:\n"; for (it=eps.begin(); it!=eps.end(); ++it) { - *it == NULL ? (void)(_ostr << "[deleted]" << "\n") : (*it)->stats(_ostr); + *it == nullptr ? (void)(_ostr << "[deleted]" << "\n") : (*it)->stats(_ostr); } _ostr << fprops_.size() << " fprops:\n"; for (it=fps.begin(); it!=fps.end(); ++it) { - *it == NULL ? (void)(_ostr << "[deleted]" << "\n") : (*it)->stats(_ostr); + *it == nullptr ? (void)(_ostr << "[deleted]" << "\n") : (*it)->stats(_ostr); } _ostr << mprops_.size() << " mprops:\n"; for (it=mps.begin(); it!=mps.end(); ++it) { - *it == NULL ? (void)(_ostr << "[deleted]" << "\n") : (*it)->stats(_ostr); + *it == nullptr ? (void)(_ostr << "[deleted]" << "\n") : (*it)->stats(_ostr); } } @@ -102,7 +97,7 @@ void BaseKernel::vprop_stats( std::string& _string ) const PropertyContainer::Properties::const_iterator it; const PropertyContainer::Properties& vps = vprops_.properties(); for (it=vps.begin(); it!=vps.end(); ++it) - if ( *it == NULL ) + if ( *it == nullptr ) _string += "[deleted] \n"; else { _string += (*it)->name(); @@ -118,7 +113,7 @@ void BaseKernel::hprop_stats( std::string& _string ) const PropertyContainer::Properties::const_iterator it; const PropertyContainer::Properties& hps = hprops_.properties(); for (it=hps.begin(); it!=hps.end(); ++it) - if ( *it == NULL ) + if ( *it == nullptr ) _string += "[deleted] \n"; else { _string += (*it)->name(); @@ -134,7 +129,7 @@ void BaseKernel::eprop_stats( std::string& _string ) const PropertyContainer::Properties::const_iterator it; const PropertyContainer::Properties& eps = eprops_.properties(); for (it=eps.begin(); it!=eps.end(); ++it) - if ( *it == NULL ) + if ( *it == nullptr ) _string += "[deleted] \n"; else { _string += (*it)->name(); @@ -149,7 +144,7 @@ void BaseKernel::fprop_stats( std::string& _string ) const PropertyContainer::Properties::const_iterator it; const PropertyContainer::Properties& fps = fprops_.properties(); for (it=fps.begin(); it!=fps.end(); ++it) - if ( *it == NULL ) + if ( *it == nullptr ) _string += "[deleted] \n"; else { _string += (*it)->name(); @@ -165,7 +160,7 @@ void BaseKernel::mprop_stats( std::string& _string ) const PropertyContainer::Properties::const_iterator it; const PropertyContainer::Properties& mps = mprops_.properties(); for (it=mps.begin(); it!=mps.end(); ++it) - if ( *it == NULL ) + if ( *it == nullptr ) _string += "[deleted] \n"; else { _string += (*it)->name(); @@ -183,7 +178,7 @@ void BaseKernel::vprop_stats(std::ostream& _ostr ) const PropertyContainer::Properties::const_iterator it; const PropertyContainer::Properties& vps = vprops_.properties(); for (it=vps.begin(); it!=vps.end(); ++it) - *it == NULL ? (void)(_ostr << "[deleted]" << "\n") : (*it)->stats(_ostr); + *it == nullptr ? (void)(_ostr << "[deleted]" << "\n") : (*it)->stats(_ostr); } void BaseKernel::hprop_stats() const @@ -195,7 +190,7 @@ void BaseKernel::hprop_stats(std::ostream& _ostr ) const PropertyContainer::Properties::const_iterator it; const PropertyContainer::Properties& hps = hprops_.properties(); for (it=hps.begin(); it!=hps.end(); ++it) - *it == NULL ? (void)(_ostr << "[deleted]" << "\n") : (*it)->stats(_ostr); + *it == nullptr ? (void)(_ostr << "[deleted]" << "\n") : (*it)->stats(_ostr); } void BaseKernel::eprop_stats() const @@ -207,7 +202,7 @@ void BaseKernel::eprop_stats(std::ostream& _ostr ) const PropertyContainer::Properties::const_iterator it; const PropertyContainer::Properties& eps = eprops_.properties(); for (it=eps.begin(); it!=eps.end(); ++it) - *it == NULL ? (void)(_ostr << "[deleted]" << "\n") : (*it)->stats(_ostr); + *it == nullptr ? (void)(_ostr << "[deleted]" << "\n") : (*it)->stats(_ostr); } void BaseKernel::fprop_stats() const @@ -219,7 +214,7 @@ void BaseKernel::fprop_stats(std::ostream& _ostr ) const PropertyContainer::Properties::const_iterator it; const PropertyContainer::Properties& fps = fprops_.properties(); for (it=fps.begin(); it!=fps.end(); ++it) - *it == NULL ? (void)(_ostr << "[deleted]" << "\n") : (*it)->stats(_ostr); + *it == nullptr ? (void)(_ostr << "[deleted]" << "\n") : (*it)->stats(_ostr); } void BaseKernel::mprop_stats() const @@ -231,7 +226,7 @@ void BaseKernel::mprop_stats(std::ostream& _ostr ) const PropertyContainer::Properties::const_iterator it; const PropertyContainer::Properties& mps = mprops_.properties(); for (it=mps.begin(); it!=mps.end(); ++it) - *it == NULL ? (void)(_ostr << "[deleted]" << "\n") : (*it)->stats(_ostr); + *it == nullptr ? (void)(_ostr << "[deleted]" << "\n") : (*it)->stats(_ostr); } diff --git a/src/OpenMesh/Core/Mesh/BaseKernel.hh b/src/OpenMesh/Core/Mesh/BaseKernel.hh index 6bca014d..0270a580 100644 --- a/src/OpenMesh/Core/Mesh/BaseKernel.hh +++ b/src/OpenMesh/Core/Mesh/BaseKernel.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= @@ -521,7 +516,7 @@ public: // Copy all properties, if build in is true // Otherwise, copy only properties without build in specifier if ( *p_it && ( _copyBuildIn || (*p_it)->name().substr(0,2) != "v:" ) ) - (*p_it)->copy(_vh_from.idx(), _vh_to.idx()); + (*p_it)->copy(static_cast(_vh_from.idx()), static_cast(_vh_to.idx())); } } @@ -695,6 +690,9 @@ public: //----------------------------------------------------- element numbers virtual size_t n_edges() const { return 0; } virtual size_t n_faces() const { return 0; } + template + size_t n_elements() const; + protected: //------------------------------------------- synchronize properties @@ -819,6 +817,16 @@ private: }; +template <> +inline size_t BaseKernel::n_elements() const { return n_vertices(); } +template <> +inline size_t BaseKernel::n_elements() const { return n_halfedges(); } +template <> +inline size_t BaseKernel::n_elements() const { return n_edges(); } +template <> +inline size_t BaseKernel::n_elements() const { return n_faces(); } + + //============================================================================= } // namespace OpenMesh //============================================================================= diff --git a/src/OpenMesh/Core/Mesh/BaseMesh.hh b/src/OpenMesh/Core/Mesh/BaseMesh.hh index bcf75ebf..359514dd 100644 --- a/src/OpenMesh/Core/Mesh/BaseMesh.hh +++ b/src/OpenMesh/Core/Mesh/BaseMesh.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= diff --git a/src/OpenMesh/Core/Mesh/Casts.hh b/src/OpenMesh/Core/Mesh/Casts.hh index 136c16f7..4a913a7f 100644 --- a/src/OpenMesh/Core/Mesh/Casts.hh +++ b/src/OpenMesh/Core/Mesh/Casts.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef OPENMESH_CASTS_HH #define OPENMESH_CASTS_HH diff --git a/src/OpenMesh/Core/Mesh/CirculatorsT.hh b/src/OpenMesh/Core/Mesh/CirculatorsT.hh index 06560599..c9c537d3 100644 --- a/src/OpenMesh/Core/Mesh/CirculatorsT.hh +++ b/src/OpenMesh/Core/Mesh/CirculatorsT.hh @@ -39,15 +39,9 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ -#ifndef OPENMESH_CIRCULATORS_HH -#define OPENMESH_CIRCULATORS_HH +#pragma once + //============================================================================= // // Vertex and Face circulators for PolyMesh/TriMesh @@ -201,7 +195,7 @@ class GenericCirculatorBaseT { public: GenericCirculatorBaseT() : mesh_(0), lap_counter_(0) {} - GenericCirculatorBaseT(mesh_ref mesh, HalfedgeHandle heh, bool end = false) : + GenericCirculatorBaseT(mesh_ref mesh, typename Mesh::HalfedgeHandle heh, bool end = false) : mesh_(&mesh), start_(heh), heh_(heh), lap_counter_(static_cast(end && heh.is_valid())) {} GenericCirculatorBaseT(const GenericCirculatorBaseT &rhs) : @@ -253,19 +247,25 @@ class GenericCirculatorBaseT { int lap_counter_; }; -template::*Handle2Value)() const, bool CW = true > -class GenericCirculatorT : protected GenericCirculatorBaseT { +//template::*Handle2Value)() const, bool CW = true > +template +class GenericCirculatorT : protected GenericCirculatorBaseT { public: + using Mesh = typename GenericCirculatorT_TraitsT::Mesh; + using value_type = typename GenericCirculatorT_TraitsT::ValueHandle; + using CenterEntityHandle = typename GenericCirculatorT_TraitsT::CenterEntityHandle; + + using smart_value_type = decltype(make_smart(std::declval(), std::declval())); + typedef std::ptrdiff_t difference_type; - typedef ValueHandle value_type; typedef const value_type& reference; - typedef const value_type* pointer; + typedef const smart_value_type* pointer; typedef std::bidirectional_iterator_tag iterator_category; typedef typename GenericCirculatorBaseT::mesh_ptr mesh_ptr; typedef typename GenericCirculatorBaseT::mesh_ref mesh_ref; - typedef GenericCirculator_ValueHandleFnsT GenericCirculator_ValueHandleFns; + typedef GenericCirculator_ValueHandleFnsT GenericCirculator_ValueHandleFns; public: GenericCirculatorT() {} @@ -274,15 +274,15 @@ class GenericCirculatorT : protected GenericCirculatorBaseT { GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_); } - GenericCirculatorT(mesh_ref mesh, HalfedgeHandle heh, bool end = false) : + GenericCirculatorT(mesh_ref mesh, typename Mesh::HalfedgeHandle heh, bool end = false) : GenericCirculatorBaseT(mesh, heh, end) { GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_); } GenericCirculatorT(const GenericCirculatorT &rhs) : GenericCirculatorBaseT(rhs) {} - friend class GenericCirculatorT; - explicit GenericCirculatorT( const GenericCirculatorT& rhs ) + friend class GenericCirculatorT; + explicit GenericCirculatorT( const GenericCirculatorT& rhs ) :GenericCirculatorBaseT(rhs){} GenericCirculatorT& operator++() { @@ -313,16 +313,14 @@ class GenericCirculatorT : protected GenericCirculatorBaseT { } /// Standard dereferencing operator. - value_type operator*() const { - // We can't use this due to a GCC6 compiler bug - const GenericCirculatorBaseT* self = this; + smart_value_type operator*() const { #ifndef NDEBUG assert(this->heh_.is_valid()); - value_type res = (self->*Handle2Value)(); + value_type res = GenericCirculatorT_TraitsT::toHandle(this->mesh_, this->heh_); assert(res.is_valid()); - return res; + return make_smart(res, this->mesh_); #else - return (self->*Handle2Value)(); + return make_smart(GenericCirculatorT_TraitsT::toHandle(this->mesh_, this->heh_), this->mesh_); #endif } @@ -362,7 +360,7 @@ class GenericCirculatorT : protected GenericCirculatorBaseT { } private: - mutable value_type pointer_deref_value; + mutable smart_value_type pointer_deref_value; }; ////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -425,19 +423,22 @@ class GenericCirculator_ValueHandleFnsT_DEPRECATED::*Handle2Value)() const> -class GenericCirculatorT_DEPRECATED : protected GenericCirculatorBaseT { +template +class GenericCirculatorT_DEPRECATED : protected GenericCirculatorBaseT { public: + using Mesh = typename GenericCirculatorT_DEPRECATED_TraitsT::Mesh; + using CenterEntityHandle = typename GenericCirculatorT_DEPRECATED_TraitsT::CenterEntityHandle; + using value_type = typename GenericCirculatorT_DEPRECATED_TraitsT::ValueHandle; + using smart_value_type = decltype (make_smart(std::declval(), std::declval())); + typedef std::ptrdiff_t difference_type; - typedef ValueHandle value_type; typedef const value_type& reference; - typedef const value_type* pointer; + typedef const smart_value_type* pointer; typedef std::bidirectional_iterator_tag iterator_category; typedef typename GenericCirculatorBaseT::mesh_ptr mesh_ptr; typedef typename GenericCirculatorBaseT::mesh_ref mesh_ref; - typedef GenericCirculator_ValueHandleFnsT_DEPRECATED GenericCirculator_ValueHandleFns; + typedef GenericCirculator_ValueHandleFnsT_DEPRECATED GenericCirculator_ValueHandleFns; public: GenericCirculatorT_DEPRECATED() {} @@ -446,7 +447,7 @@ class GenericCirculatorT_DEPRECATED : protected GenericCirculatorBaseT { GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_); } - GenericCirculatorT_DEPRECATED(mesh_ref mesh, HalfedgeHandle heh, bool end = false) : + GenericCirculatorT_DEPRECATED(mesh_ref mesh, typename Mesh::HalfedgeHandle heh, bool end = false) : GenericCirculatorBaseT(mesh, heh, end) { GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_); @@ -470,7 +471,7 @@ class GenericCirculatorT_DEPRECATED : protected GenericCirculatorBaseT { To be save, you can use the CW/CCW circulator definitions, which behave\ the same as the original ones, without the previously mentioned issues." - DEPRECATED( DECREMENT_DEPRECATED_WARNINGS_TEXT ) + OM_DEPRECATED( DECREMENT_DEPRECATED_WARNINGS_TEXT ) #endif // NO_DECREMENT_DEPRECATED_WARNINGS GenericCirculatorT_DEPRECATED& operator--() { assert(this->mesh_); @@ -488,7 +489,7 @@ class GenericCirculatorT_DEPRECATED : protected GenericCirculatorBaseT { /// Post-decrement #ifndef NO_DECREMENT_DEPRECATED_WARNINGS - DEPRECATED( DECREMENT_DEPRECATED_WARNINGS_TEXT ) + OM_DEPRECATED( DECREMENT_DEPRECATED_WARNINGS_TEXT ) #undef DECREMENT_DEPRECATED_WARNINGS_TEXT #endif //NO_DECREMENT_DEPRECATED_WARNINGS GenericCirculatorT_DEPRECATED operator--(int) { @@ -499,16 +500,14 @@ class GenericCirculatorT_DEPRECATED : protected GenericCirculatorBaseT { } /// Standard dereferencing operator. - value_type operator*() const { - // We can't use this due to a GCC6 compiler bug - const GenericCirculatorBaseT* self = this; + smart_value_type operator*() const { #ifndef NDEBUG assert(this->heh_.is_valid()); - value_type res = (self->*Handle2Value)(); + value_type res = (GenericCirculatorT_DEPRECATED_TraitsT::toHandle(this->mesh_, this->heh_)); assert(res.is_valid()); - return res; + return make_smart(res, this->mesh_); #else - return (self->*Handle2Value)(); + return make_smart(GenericCirculatorT_DEPRECATED_TraitsT::toHandle(this->mesh_, this->heh_), this->mesh_); #endif } @@ -542,17 +541,17 @@ class GenericCirculatorT_DEPRECATED : protected GenericCirculatorBaseT { return GenericCirculator_ValueHandleFns::is_valid(this->heh_,this->start_, this->lap_counter_); } - DEPRECATED("current_halfedge_handle() is an implementation detail and should not be accessed from outside the iterator class.") + OM_DEPRECATED("current_halfedge_handle() is an implementation detail and should not be accessed from outside the iterator class.") /** * \deprecated * current_halfedge_handle() is an implementation detail and should not * be accessed from outside the iterator class. */ - const HalfedgeHandle ¤t_halfedge_handle() const { + const typename Mesh::HalfedgeHandle ¤t_halfedge_handle() const { return this->heh_; } - DEPRECATED("Do not use this error prone implicit cast. Compare to end-iterator or use is_valid(), instead.") + OM_DEPRECATED("Do not use this error prone implicit cast. Compare to end-iterator or use is_valid(), instead.") /** * \deprecated * Do not use this error prone implicit cast. Compare to the @@ -567,8 +566,8 @@ class GenericCirculatorT_DEPRECATED : protected GenericCirculatorBaseT { * \deprecated * This function clutters your code. Use dereferencing operators -> and * instead. */ - DEPRECATED("This function clutters your code. Use dereferencing operators -> and * instead.") - value_type handle() const { + OM_DEPRECATED("This function clutters your code. Use dereferencing operators -> and * instead.") + smart_value_type handle() const { return **this; } @@ -578,7 +577,7 @@ class GenericCirculatorT_DEPRECATED : protected GenericCirculatorBaseT { * Implicit casts of iterators are unsafe. Use dereferencing operators * -> and * instead. */ - DEPRECATED("Implicit casts of iterators are unsafe. Use dereferencing operators -> and * instead.") + OM_DEPRECATED("Implicit casts of iterators are unsafe. Use dereferencing operators -> and * instead.") operator value_type() const { return **this; } @@ -589,10 +588,9 @@ class GenericCirculatorT_DEPRECATED : protected GenericCirculatorBaseT { } private: - mutable value_type pointer_deref_value; + mutable smart_value_type pointer_deref_value; }; } // namespace Iterators } // namespace OpenMesh -#endif diff --git a/src/OpenMesh/Core/Templates/newClassT.cc b/src/OpenMesh/Core/Mesh/DefaultPolyMesh.hh similarity index 82% rename from src/OpenMesh/Core/Templates/newClassT.cc rename to src/OpenMesh/Core/Mesh/DefaultPolyMesh.hh index e89b6da1..56bdda9d 100644 --- a/src/OpenMesh/Core/Templates/newClassT.cc +++ b/src/OpenMesh/Core/Mesh/DefaultPolyMesh.hh @@ -1,7 +1,7 @@ /* ========================================================================= * * * * OpenMesh * - * Copyright (c) 2001-2015, RWTH-Aachen University * + * Copyright (c) 2001-2019, RWTH-Aachen University * * Department of Computer Graphics and Multimedia * * All rights reserved. * * www.openmesh.org * @@ -39,39 +39,28 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ -//============================================================================= -// -// CLASS newClass - IMPLEMENTATION -// -//============================================================================= +#ifndef OPENMESH_DEFAULTPOLYMESH_HH +#define OPENMESH_DEFAULTPOLYMESH_HH -#define OPENMESH_NEWCLASS_C //== INCLUDES ================================================================= -#include - +#include +#include //== NAMESPACES =============================================================== namespace OpenMesh { +//== TYPEDEFS ================================================================= -//== IMPLEMENTATION ========================================================== - - - -//----------------------------------------------------------------------------- - - +typedef PolyMesh_ArrayKernelT PolyMesh; //============================================================================= } // namespace OpenMesh //============================================================================= + +//============================================================================= +#endif // OPENMESH_DEFAULTPOLYMESH_HH defined +//============================================================================= diff --git a/src/OpenMesh/Core/Mesh/DefaultTriMesh.hh b/src/OpenMesh/Core/Mesh/DefaultTriMesh.hh new file mode 100644 index 00000000..94fb4039 --- /dev/null +++ b/src/OpenMesh/Core/Mesh/DefaultTriMesh.hh @@ -0,0 +1,66 @@ +/* ========================================================================= * + * * + * OpenMesh * + * Copyright (c) 2001-2019, RWTH-Aachen University * + * Department of Computer Graphics and Multimedia * + * All rights reserved. * + * www.openmesh.org * + * * + *---------------------------------------------------------------------------* + * This file is part of OpenMesh. * + *---------------------------------------------------------------------------* + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * 1. Redistributions of source code must retain the above copyright notice, * + * this list of conditions and the following disclaimer. * + * * + * 2. Redistributions in binary form must reproduce the above copyright * + * notice, this list of conditions and the following disclaimer in the * + * documentation and/or other materials provided with the distribution. * + * * + * 3. Neither the name of the copyright holder nor the names of its * + * contributors may be used to endorse or promote products derived from * + * this software without specific prior written permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER * + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * + * * + * ========================================================================= */ + + +#ifndef OPENMESH_DEFAULTTRIMESH_HH +#define OPENMESH_DEFAULTTRIMESH_HH + + +//== INCLUDES ================================================================= + +#include +#include + +//== NAMESPACES =============================================================== + +namespace OpenMesh { + +//== TYPEDEFS ================================================================= + +typedef TriMesh_ArrayKernelT TriMesh; + +//============================================================================= +} // namespace OpenMesh +//============================================================================= + +//============================================================================= +#endif // OPENMESH_DEFAULTTRIMESH_HH defined +//============================================================================= diff --git a/src/OpenMesh/Core/Mesh/FinalMeshItemsT.hh b/src/OpenMesh/Core/Mesh/FinalMeshItemsT.hh index cbed2e51..9952e4eb 100644 --- a/src/OpenMesh/Core/Mesh/FinalMeshItemsT.hh +++ b/src/OpenMesh/Core/Mesh/FinalMeshItemsT.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef OPENMESH_MESH_ITEMS_HH #define OPENMESH_MESH_ITEMS_HH diff --git a/src/OpenMesh/Core/Mesh/Handles.hh b/src/OpenMesh/Core/Mesh/Handles.hh index 6cbb8ac4..0f237e20 100644 --- a/src/OpenMesh/Core/Mesh/Handles.hh +++ b/src/OpenMesh/Core/Mesh/Handles.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef OPENMESH_HANDLES_HH #define OPENMESH_HANDLES_HH @@ -64,7 +59,7 @@ namespace OpenMesh { /// Base class for all handle types -class BaseHandle +class OPENMESHDLLEXPORT BaseHandle { public: @@ -122,33 +117,42 @@ inline std::ostream& operator<<(std::ostream& _os, const BaseHandle& _hnd) /// Handle for a vertex entity -struct VertexHandle : public BaseHandle +struct OPENMESHDLLEXPORT VertexHandle : public BaseHandle { explicit VertexHandle(int _idx=-1) : BaseHandle(_idx) {} }; /// Handle for a halfedge entity -struct HalfedgeHandle : public BaseHandle +struct OPENMESHDLLEXPORT HalfedgeHandle : public BaseHandle { explicit HalfedgeHandle(int _idx=-1) : BaseHandle(_idx) {} }; /// Handle for a edge entity -struct EdgeHandle : public BaseHandle +struct OPENMESHDLLEXPORT EdgeHandle : public BaseHandle { explicit EdgeHandle(int _idx=-1) : BaseHandle(_idx) {} }; /// Handle for a face entity -struct FaceHandle : public BaseHandle +struct OPENMESHDLLEXPORT FaceHandle : public BaseHandle { explicit FaceHandle(int _idx=-1) : BaseHandle(_idx) {} }; +/// Handle type for meshes to simplify some template programming +struct OPENMESHDLLEXPORT MeshHandle : public BaseHandle +{ + explicit MeshHandle(int _idx=-1) : BaseHandle(_idx) {} +}; + + + + //============================================================================= } // namespace OpenMesh //============================================================================= @@ -165,8 +169,9 @@ namespace std { template <> struct hash - : public std::unary_function { + typedef OpenMesh::BaseHandle argument_type; + typedef std::size_t result_type; std::size_t operator()(const OpenMesh::BaseHandle& h) const { @@ -176,8 +181,9 @@ struct hash template <> struct hash - : public std::unary_function { + typedef OpenMesh::VertexHandle argument_type; + typedef std::size_t result_type; std::size_t operator()(const OpenMesh::VertexHandle& h) const { @@ -187,9 +193,11 @@ struct hash template <> struct hash - : public std::unary_function { + typedef OpenMesh::HalfedgeHandle argument_type; + typedef std::size_t result_type; + std::size_t operator()(const OpenMesh::HalfedgeHandle& h) const { return h.idx(); @@ -198,9 +206,11 @@ struct hash template <> struct hash - : public std::unary_function { + typedef OpenMesh::EdgeHandle argument_type; + typedef std::size_t result_type; + std::size_t operator()(const OpenMesh::EdgeHandle& h) const { return h.idx(); @@ -209,9 +219,11 @@ struct hash template <> struct hash - : public std::unary_function { + typedef OpenMesh::FaceHandle argument_type; + typedef std::size_t result_type; + std::size_t operator()(const OpenMesh::FaceHandle& h) const { return h.idx(); diff --git a/src/OpenMesh/Core/Mesh/IteratorsT.hh b/src/OpenMesh/Core/Mesh/IteratorsT.hh index 38df6ecf..446d1cc3 100644 --- a/src/OpenMesh/Core/Mesh/IteratorsT.hh +++ b/src/OpenMesh/Core/Mesh/IteratorsT.hh @@ -39,15 +39,8 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ -#ifndef OPENMESH_ITERATORS_HH -#define OPENMESH_ITERATORS_HH +#pragma once //============================================================================= // @@ -94,24 +87,22 @@ class GenericIteratorT { typedef value_handle value_type; typedef std::bidirectional_iterator_tag iterator_category; typedef std::ptrdiff_t difference_type; - typedef const value_type& reference; - typedef const value_type* pointer; typedef const Mesh* mesh_ptr; typedef const Mesh& mesh_ref; + typedef decltype(make_smart(std::declval(), std::declval())) SmartHandle; + typedef const SmartHandle& reference; + typedef const SmartHandle* pointer; /// Default constructor. GenericIteratorT() - : mesh_(0), skip_bits_(0) + : hnd_(make_smart(ValueHandle(),nullptr)), skip_bits_(0) {} /// Construct with mesh and a target handle. GenericIteratorT(mesh_ref _mesh, value_handle _hnd, bool _skip=false) - : mesh_(&_mesh), hnd_(_hnd), skip_bits_(0) + : hnd_(make_smart(_hnd, _mesh)), skip_bits_(0) { if (_skip) enable_skipping(); - - // Set vertex handle invalid if the mesh contains no vertex - if((mesh_->*PrimitiveCountMember)() == 0) hnd_ = value_handle(-1); } /// Standard dereferencing operator. @@ -129,7 +120,7 @@ class GenericIteratorT { * \deprecated * This function clutters your code. Use dereferencing operators -> and * instead. */ - DEPRECATED("This function clutters your code. Use dereferencing operators -> and * instead.") + OM_DEPRECATED("This function clutters your code. Use dereferencing operators -> and * instead.") value_handle handle() const { return hnd_; } @@ -140,14 +131,14 @@ class GenericIteratorT { * Implicit casts of iterators are unsafe. Use dereferencing operators * -> and * instead. */ - DEPRECATED("Implicit casts of iterators are unsafe. Use dereferencing operators -> and * instead.") + OM_DEPRECATED("Implicit casts of iterators are unsafe. Use dereferencing operators -> and * instead.") operator value_handle() const { return hnd_; } /// Are two iterators equal? Only valid if they refer to the same mesh! bool operator==(const GenericIteratorT& _rhs) const { - return ((mesh_ == _rhs.mesh_) && (hnd_ == _rhs.hnd_)); + return ((hnd_.mesh() == _rhs.hnd_.mesh()) && (hnd_ == _rhs.hnd_)); } /// Not equal? @@ -218,7 +209,7 @@ class GenericIteratorT { /// Turn on skipping: automatically skip deleted/hidden elements void enable_skipping() { - if (mesh_ && (mesh_->*PrimitiveStatusMember)()) { + if (hnd_.mesh() && (hnd_.mesh()->*PrimitiveStatusMember)()) { Attributes::StatusInfo status; status.set_deleted(true); status.set_hidden(true); @@ -236,21 +227,20 @@ class GenericIteratorT { private: void skip_fwd() { - assert(mesh_ && skip_bits_); - while ((hnd_.idx() < (signed) (mesh_->*PrimitiveCountMember)()) - && (mesh_->status(hnd_).bits() & skip_bits_)) + assert(hnd_.mesh() && skip_bits_); + while ((hnd_.idx() < (signed) (hnd_.mesh()->*PrimitiveCountMember)()) + && (hnd_.mesh()->status(hnd_).bits() & skip_bits_)) hnd_.__increment(); } void skip_bwd() { - assert(mesh_ && skip_bits_); - while ((hnd_.idx() >= 0) && (mesh_->status(hnd_).bits() & skip_bits_)) + assert(hnd_.mesh() && skip_bits_); + while ((hnd_.idx() >= 0) && (hnd_.mesh()->status(hnd_).bits() & skip_bits_)) hnd_.__decrement(); } protected: - mesh_ptr mesh_; - value_handle hnd_; + SmartHandle hnd_; unsigned int skip_bits_; }; @@ -258,5 +248,3 @@ class GenericIteratorT { } // namespace Iterators } // namespace OpenMesh //============================================================================= -#endif -//============================================================================= diff --git a/src/OpenMesh/Core/Mesh/PolyConnectivity.cc b/src/OpenMesh/Core/Mesh/PolyConnectivity.cc index e311f5cb..e2eaf45c 100644 --- a/src/OpenMesh/Core/Mesh/PolyConnectivity.cc +++ b/src/OpenMesh/Core/Mesh/PolyConnectivity.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //== IMPLEMENTATION ========================================================== #include @@ -59,8 +54,7 @@ const PolyConnectivity::FaceHandle PolyConnectivity::InvalidFaceHandle; //----------------------------------------------------------------------------- -PolyConnectivity::HalfedgeHandle -PolyConnectivity::find_halfedge(VertexHandle _start_vh, VertexHandle _end_vh ) const +SmartHalfedgeHandle PolyConnectivity::find_halfedge(VertexHandle _start_vh, VertexHandle _end_vh ) const { assert(_start_vh.is_valid() && _end_vh.is_valid()); @@ -68,7 +62,7 @@ PolyConnectivity::find_halfedge(VertexHandle _start_vh, VertexHandle _end_vh ) c if (to_vertex_handle(*voh_it) == _end_vh) return *voh_it; - return InvalidHalfedgeHandle; + return make_smart(InvalidHalfedgeHandle, this); } @@ -104,6 +98,7 @@ bool PolyConnectivity::is_manifold(VertexHandle _vh) const } //----------------------------------------------------------------------------- + void PolyConnectivity::adjust_outgoing_halfedge(VertexHandle _vh) { for (ConstVertexOHalfedgeIter vh_it=cvoh_iter(_vh); vh_it.is_valid(); ++vh_it) @@ -118,7 +113,7 @@ void PolyConnectivity::adjust_outgoing_halfedge(VertexHandle _vh) //----------------------------------------------------------------------------- -PolyConnectivity::FaceHandle +SmartFaceHandle PolyConnectivity::add_face(const VertexHandle* _vertex_handles, size_t _vhs_size) { VertexHandle vh; @@ -147,7 +142,7 @@ PolyConnectivity::add_face(const VertexHandle* _vertex_handles, size_t _vhs_size if ( !is_boundary(_vertex_handles[i]) ) { omerr() << "PolyMeshT::add_face: complex vertex\n"; - return InvalidFaceHandle; + return make_smart(InvalidFaceHandle, this); } // Initialise edge attributes @@ -159,7 +154,7 @@ PolyConnectivity::add_face(const VertexHandle* _vertex_handles, size_t _vhs_size if (!edgeData_[i].is_new && !is_boundary(edgeData_[i].halfedge_handle)) { omerr() << "PolyMeshT::add_face: complex edge\n"; - return InvalidFaceHandle; + return make_smart(InvalidFaceHandle, this); } } @@ -191,7 +186,7 @@ PolyConnectivity::add_face(const VertexHandle* _vertex_handles, size_t _vhs_size if (boundary_prev == inner_prev) { omerr() << "PolyMeshT::add_face: patch re-linking failed\n"; - return InvalidFaceHandle; + return make_smart(InvalidFaceHandle, this); } assert(is_boundary(boundary_prev)); @@ -302,12 +297,12 @@ PolyConnectivity::add_face(const VertexHandle* _vertex_handles, size_t _vhs_size if (edgeData_[i].needs_adjust) adjust_outgoing_halfedge(_vertex_handles[i]); - return fh; + return make_smart(fh, this); } //----------------------------------------------------------------------------- -FaceHandle PolyConnectivity::add_face(VertexHandle _vh0, VertexHandle _vh1, VertexHandle _vh2, VertexHandle _vh3) +SmartFaceHandle PolyConnectivity::add_face(VertexHandle _vh0, VertexHandle _vh1, VertexHandle _vh2, VertexHandle _vh3) { VertexHandle vhs[4] = { _vh0, _vh1, _vh2, _vh3 }; return add_face(vhs, 4); @@ -315,7 +310,7 @@ FaceHandle PolyConnectivity::add_face(VertexHandle _vh0, VertexHandle _vh1, Vert //----------------------------------------------------------------------------- -FaceHandle PolyConnectivity::add_face(VertexHandle _vh0, VertexHandle _vh1, VertexHandle _vh2) +SmartFaceHandle PolyConnectivity::add_face(VertexHandle _vh0, VertexHandle _vh1, VertexHandle _vh2) { VertexHandle vhs[3] = { _vh0, _vh1, _vh2 }; return add_face(vhs, 3); @@ -323,9 +318,17 @@ FaceHandle PolyConnectivity::add_face(VertexHandle _vh0, VertexHandle _vh1, Vert //----------------------------------------------------------------------------- -FaceHandle PolyConnectivity::add_face(const std::vector& _vhandles) +SmartFaceHandle PolyConnectivity::add_face(const std::vector& _vhandles) { return add_face(&_vhandles.front(), _vhandles.size()); } +//----------------------------------------------------------------------------- + +SmartFaceHandle PolyConnectivity::add_face(const std::vector& _vhandles) +{ + std::vector vhandles(_vhandles.begin(), _vhandles.end()); + return add_face(&vhandles.front(), vhandles.size()); +} + //----------------------------------------------------------------------------- bool PolyConnectivity::is_collapse_ok(HalfedgeHandle v0v1) @@ -364,14 +367,16 @@ bool PolyConnectivity::is_collapse_ok(HalfedgeHandle v0v1) //the edges v1-vl and vl-v0 must not be both boundary edges //this test makes only sense in a polymesh if the side face is a triangle + VertexHandle vl; if (!is_boundary(v0v1)) { if (v0v1_triangle) { - //VertexHandle vl = to_vertex_handle(next_halfedge_handle(v0v1)); - HalfedgeHandle h1 = next_halfedge_handle(v0v1); HalfedgeHandle h2 = next_halfedge_handle(h1); + + vl = to_vertex_handle(h1); + if (is_boundary(opposite_halfedge_handle(h1)) && is_boundary(opposite_halfedge_handle(h2))) return false; } @@ -379,19 +384,24 @@ bool PolyConnectivity::is_collapse_ok(HalfedgeHandle v0v1) //the edges v0-vr and vr-v1 must not be both boundary edges //this test makes only sense in a polymesh if the side face is a triangle + VertexHandle vr; if (!is_boundary(v1v0)) { if (v1v0_triangle) { - //VertexHandle vr = to_vertex_handle(next_halfedge_handle(v1v0)); - HalfedgeHandle h1 = next_halfedge_handle(v1v0); HalfedgeHandle h2 = next_halfedge_handle(h1); + + vr = to_vertex_handle(h1); + if (is_boundary(opposite_halfedge_handle(h1)) && is_boundary(opposite_halfedge_handle(h2))) return false; } } + // if vl and vr are equal and valid (e.g. triangle case) -> fail + if ( vl.is_valid() && (vl == vr)) return false; + // edge between two boundary vertices should be a boundary edge if ( is_boundary(v0) && is_boundary(v1) && !is_boundary(v0v1) && !is_boundary(v1v0)) return false; @@ -621,101 +631,6 @@ void PolyConnectivity::delete_face(FaceHandle _fh, bool _delete_isolated_vertice adjust_outgoing_halfedge(*v_it); } -//----------------------------------------------------------------------------- -PolyConnectivity::VertexIter PolyConnectivity::vertices_begin() -{ - return VertexIter(*this, VertexHandle(0)); -} - -//----------------------------------------------------------------------------- -PolyConnectivity::ConstVertexIter PolyConnectivity::vertices_begin() const -{ - return ConstVertexIter(*this, VertexHandle(0)); -} - -//----------------------------------------------------------------------------- -PolyConnectivity::VertexIter PolyConnectivity::vertices_end() -{ - return VertexIter(*this, VertexHandle( int(n_vertices() ) )); -} - -//----------------------------------------------------------------------------- -PolyConnectivity::ConstVertexIter PolyConnectivity::vertices_end() const -{ - return ConstVertexIter(*this, VertexHandle( int(n_vertices()) )); -} - -//----------------------------------------------------------------------------- -PolyConnectivity::HalfedgeIter PolyConnectivity::halfedges_begin() -{ - return HalfedgeIter(*this, HalfedgeHandle(0)); -} - -//----------------------------------------------------------------------------- -PolyConnectivity::ConstHalfedgeIter PolyConnectivity::halfedges_begin() const -{ - return ConstHalfedgeIter(*this, HalfedgeHandle(0)); -} - -//----------------------------------------------------------------------------- -PolyConnectivity::HalfedgeIter PolyConnectivity::halfedges_end() -{ - return HalfedgeIter(*this, HalfedgeHandle(int(n_halfedges()))); -} - -//----------------------------------------------------------------------------- -PolyConnectivity::ConstHalfedgeIter PolyConnectivity::halfedges_end() const -{ - return ConstHalfedgeIter(*this, HalfedgeHandle(int(n_halfedges()))); -} - -//----------------------------------------------------------------------------- -PolyConnectivity::EdgeIter PolyConnectivity::edges_begin() -{ - return EdgeIter(*this, EdgeHandle(0)); -} - -//----------------------------------------------------------------------------- -PolyConnectivity::ConstEdgeIter PolyConnectivity::edges_begin() const -{ - return ConstEdgeIter(*this, EdgeHandle(0)); -} - -//----------------------------------------------------------------------------- -PolyConnectivity::EdgeIter PolyConnectivity::edges_end() -{ - return EdgeIter(*this, EdgeHandle(int(n_edges()))); -} - -//----------------------------------------------------------------------------- -PolyConnectivity::ConstEdgeIter PolyConnectivity::edges_end() const -{ - return ConstEdgeIter(*this, EdgeHandle(int(n_edges()))); -} - -//----------------------------------------------------------------------------- -PolyConnectivity::FaceIter PolyConnectivity::faces_begin() -{ - return FaceIter(*this, FaceHandle(0)); -} - -//----------------------------------------------------------------------------- -PolyConnectivity::ConstFaceIter PolyConnectivity::faces_begin() const -{ - return ConstFaceIter(*this, FaceHandle(0)); -} - -//----------------------------------------------------------------------------- -PolyConnectivity::FaceIter PolyConnectivity::faces_end() -{ - return FaceIter(*this, FaceHandle(int(n_faces()))); -} - -//----------------------------------------------------------------------------- -PolyConnectivity::ConstFaceIter PolyConnectivity::faces_end() const -{ - return ConstFaceIter(*this, FaceHandle(int(n_faces()))); -} //----------------------------------------------------------------------------- void PolyConnectivity::collapse(HalfedgeHandle _hh) diff --git a/src/OpenMesh/Core/Mesh/PolyConnectivity.hh b/src/OpenMesh/Core/Mesh/PolyConnectivity.hh index 3a93941f..e1a27338 100644 --- a/src/OpenMesh/Core/Mesh/PolyConnectivity.hh +++ b/src/OpenMesh/Core/Mesh/PolyConnectivity.hh @@ -39,23 +39,74 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef OPENMESH_POLYCONNECTIVITY_HH #define OPENMESH_POLYCONNECTIVITY_HH #include -#include -#include +#include namespace OpenMesh { +namespace Iterators +{ + template + class GenericIteratorT; + + template + class GenericCirculatorBaseT; + + template + class GenericCirculatorT_DEPRECATED; + + template + class GenericCirculatorT; +} + +template +class EntityRange; + +template< + typename CONTAINER_T, + typename ITER_T, + ITER_T (CONTAINER_T::*begin_fn)() const, + ITER_T (CONTAINER_T::*end_fn)() const> +struct RangeTraitT +{ + using CONTAINER_TYPE = CONTAINER_T; + using ITER_TYPE = ITER_T; + static ITER_TYPE begin(const CONTAINER_TYPE& _container) { return (_container.*begin_fn)(); } + static ITER_TYPE end(const CONTAINER_TYPE& _container) { return (_container.*end_fn)(); } +}; + + +template +class CirculatorRange; + +template< + typename CONTAINER_T, + typename ITER_T, + typename CENTER_ENTITY_T, + typename TO_ENTITY_T, + ITER_T (CONTAINER_T::*begin_fn)(CENTER_ENTITY_T) const, + ITER_T (CONTAINER_T::*end_fn)(CENTER_ENTITY_T) const> +struct CirculatorRangeTraitT +{ + using CONTAINER_TYPE = CONTAINER_T; + using ITER_TYPE = ITER_T; + using CENTER_ENTITY_TYPE = CENTER_ENTITY_T; + using TO_ENTITYE_TYPE = TO_ENTITY_T; + static ITER_TYPE begin(const CONTAINER_TYPE& _container, CENTER_ENTITY_TYPE _ce) { return (_container.*begin_fn)(_ce); } + static ITER_TYPE end(const CONTAINER_TYPE& _container, CENTER_ENTITY_TYPE _ce) { return (_container.*end_fn)(_ce); } +}; + +struct SmartVertexHandle; +struct SmartHalfedgeHandle; +struct SmartEdgeHandle; +struct SmartFaceHandle; + /** \brief Connectivity Class for polygonal meshes */ class OPENMESHDLLEXPORT PolyConnectivity : public ArrayKernel @@ -106,99 +157,122 @@ public: * Vertex-centered circulators */ + struct VertexVertexTraits + { + using Mesh = This; + using CenterEntityHandle = This::VertexHandle; + using ValueHandle = This::VertexHandle; + static ValueHandle toHandle(const Mesh* const _mesh, This::HalfedgeHandle _heh) { return _mesh->to_vertex_handle(_heh);} + }; + + /** * Enumerates 1-ring vertices in a clockwise fashion. */ - typedef Iterators::GenericCirculatorT_DEPRECATED::toVertexHandle> - VertexVertexIter; - typedef Iterators::GenericCirculatorT::toVertexHandle> VertexVertexCWIter; + typedef Iterators::GenericCirculatorT_DEPRECATED VertexVertexIter; + typedef Iterators::GenericCirculatorT VertexVertexCWIter; /** * Enumerates 1-ring vertices in a counter clockwise fashion. */ - typedef Iterators::GenericCirculatorT::toVertexHandle, false> - VertexVertexCCWIter; + typedef Iterators::GenericCirculatorT VertexVertexCCWIter; + + + struct VertexHalfedgeTraits + { + using Mesh = This; + using CenterEntityHandle = This::VertexHandle; + using ValueHandle = This::HalfedgeHandle; + static ValueHandle toHandle(const Mesh* const /*_mesh*/, This::HalfedgeHandle _heh) { return _heh;} + }; /** * Enumerates outgoing half edges in a clockwise fashion. */ - typedef Iterators::GenericCirculatorT_DEPRECATED::toHalfedgeHandle> - VertexOHalfedgeIter; - typedef Iterators::GenericCirculatorT::toHalfedgeHandle> VertexOHalfedgeCWIter; + typedef Iterators::GenericCirculatorT_DEPRECATED VertexOHalfedgeIter; + typedef Iterators::GenericCirculatorT VertexOHalfedgeCWIter; /** * Enumerates outgoing half edges in a counter clockwise fashion. */ - typedef Iterators::GenericCirculatorT::toHalfedgeHandle, false> - VertexOHalfedgeCCWIter; + typedef Iterators::GenericCirculatorT VertexOHalfedgeCCWIter; + + struct VertexOppositeHalfedgeTraits + { + using Mesh = This; + using CenterEntityHandle = This::VertexHandle; + using ValueHandle = This::HalfedgeHandle; + static ValueHandle toHandle(const Mesh* const _mesh, This::HalfedgeHandle _heh) { return _mesh->opposite_halfedge_handle(_heh); } + }; /** * Enumerates incoming half edges in a clockwise fashion. */ - typedef Iterators::GenericCirculatorT_DEPRECATED::toOppositeHalfedgeHandle> - VertexIHalfedgeIter; - typedef Iterators::GenericCirculatorT::toOppositeHalfedgeHandle> VertexIHalfedgeCWIter; + typedef Iterators::GenericCirculatorT_DEPRECATED VertexIHalfedgeIter; + typedef Iterators::GenericCirculatorT VertexIHalfedgeCWIter; /** * Enumerates incoming half edges in a counter clockwise fashion. */ - typedef Iterators::GenericCirculatorT::toOppositeHalfedgeHandle, false> - VertexIHalfedgeCCWIter; + typedef Iterators::GenericCirculatorT VertexIHalfedgeCCWIter; + + + struct VertexFaceTraits + { + using Mesh = This; + using CenterEntityHandle = This::VertexHandle; + using ValueHandle = This::FaceHandle; + static ValueHandle toHandle(const Mesh* const _mesh, This::HalfedgeHandle _heh) { return static_cast(_mesh)->face_handle(_heh); } + }; /** * Enumerates incident faces in a clockwise fashion. */ - typedef Iterators::GenericCirculatorT_DEPRECATED::toFaceHandle> - VertexFaceIter; - typedef Iterators::GenericCirculatorT::toFaceHandle> VertexFaceCWIter; + typedef Iterators::GenericCirculatorT_DEPRECATED VertexFaceIter; + typedef Iterators::GenericCirculatorT VertexFaceCWIter; /** * Enumerates incident faces in a counter clockwise fashion. */ - typedef Iterators::GenericCirculatorT::toFaceHandle, false> - VertexFaceCCWIter; + typedef Iterators::GenericCirculatorT VertexFaceCCWIter; + + + struct VertexEdgeTraits + { + using Mesh = This; + using CenterEntityHandle = This::VertexHandle; + using ValueHandle = This::EdgeHandle; + static ValueHandle toHandle(const Mesh* const _mesh, This::HalfedgeHandle _heh) { return static_cast(_mesh)->edge_handle(_heh); } + }; /** * Enumerates incident edges in a clockwise fashion. */ - typedef Iterators::GenericCirculatorT_DEPRECATED::toEdgeHandle> - VertexEdgeIter; - typedef Iterators::GenericCirculatorT::toEdgeHandle> VertexEdgeCWIter; + typedef Iterators::GenericCirculatorT_DEPRECATED VertexEdgeIter; + typedef Iterators::GenericCirculatorT VertexEdgeCWIter; /** * Enumerates incident edges in a counter clockwise fashion. */ - typedef Iterators::GenericCirculatorT::toEdgeHandle, false> - VertexEdgeCCWIter; + typedef Iterators::GenericCirculatorT VertexEdgeCCWIter; + + + struct FaceHalfedgeTraits + { + using Mesh = This; + using CenterEntityHandle = This::FaceHandle; + using ValueHandle = This::HalfedgeHandle; + static ValueHandle toHandle(const Mesh* const /*_mesh*/, This::HalfedgeHandle _heh) { return _heh; } + }; /** * Identical to #FaceHalfedgeIter. God knows why this typedef exists. */ - typedef Iterators::GenericCirculatorT_DEPRECATED::toHalfedgeHandle> - HalfedgeLoopIter; - typedef Iterators::GenericCirculatorT::toHalfedgeHandle, false> HalfedgeLoopCWIter; + typedef Iterators::GenericCirculatorT_DEPRECATED HalfedgeLoopIter; + typedef Iterators::GenericCirculatorT HalfedgeLoopCWIter; /** * Identical to #FaceHalfedgeIter. God knows why this typedef exists. */ - typedef Iterators::GenericCirculatorT::toHalfedgeHandle> - HalfedgeLoopCCWIter; + typedef Iterators::GenericCirculatorT HalfedgeLoopCCWIter; typedef VertexVertexIter ConstVertexVertexIter; typedef VertexVertexCWIter ConstVertexVertexCWIter; @@ -220,69 +294,75 @@ public: * Face-centered circulators */ + struct FaceVertexTraits + { + using Mesh = This; + using CenterEntityHandle = This::FaceHandle; + using ValueHandle = This::VertexHandle; + static ValueHandle toHandle(const Mesh* const _mesh, This::HalfedgeHandle _heh) { return static_cast(_mesh)->to_vertex_handle(_heh); } + }; + /** * Enumerate incident vertices in a counter clockwise fashion. */ - typedef Iterators::GenericCirculatorT_DEPRECATED::toVertexHandle> - FaceVertexIter; - typedef Iterators::GenericCirculatorT::toVertexHandle> FaceVertexCCWIter; + typedef Iterators::GenericCirculatorT_DEPRECATED FaceVertexIter; + typedef Iterators::GenericCirculatorT FaceVertexCCWIter; /** * Enumerate incident vertices in a clockwise fashion. */ - typedef Iterators::GenericCirculatorT::toVertexHandle, false> - FaceVertexCWIter; + typedef Iterators::GenericCirculatorT FaceVertexCWIter; /** * Enumerate incident half edges in a counter clockwise fashion. */ - typedef Iterators::GenericCirculatorT_DEPRECATED::toHalfedgeHandle> - FaceHalfedgeIter; - typedef Iterators::GenericCirculatorT::toHalfedgeHandle> FaceHalfedgeCCWIter; + typedef Iterators::GenericCirculatorT_DEPRECATED FaceHalfedgeIter; + typedef Iterators::GenericCirculatorT FaceHalfedgeCCWIter; /** * Enumerate incident half edges in a clockwise fashion. */ - typedef Iterators::GenericCirculatorT::toHalfedgeHandle, false> - FaceHalfedgeCWIter; + typedef Iterators::GenericCirculatorT FaceHalfedgeCWIter; + + + struct FaceEdgeTraits + { + using Mesh = This; + using CenterEntityHandle = This::FaceHandle; + using ValueHandle = This::EdgeHandle; + static ValueHandle toHandle(const Mesh* const _mesh, This::HalfedgeHandle _heh) { return static_cast(_mesh)->edge_handle(_heh); } + }; /** * Enumerate incident edges in a counter clockwise fashion. */ - typedef Iterators::GenericCirculatorT_DEPRECATED::toEdgeHandle> - FaceEdgeIter; - typedef Iterators::GenericCirculatorT::toEdgeHandle> FaceEdgeCCWIter; + typedef Iterators::GenericCirculatorT_DEPRECATED FaceEdgeIter; + typedef Iterators::GenericCirculatorT FaceEdgeCCWIter; /** * Enumerate incident edges in a clockwise fashion. */ - typedef Iterators::GenericCirculatorT::toEdgeHandle, false> - FaceEdgeCWIter; + typedef Iterators::GenericCirculatorT FaceEdgeCWIter; + + + struct FaceFaceTraits + { + using Mesh = This; + using CenterEntityHandle = This::FaceHandle; + using ValueHandle = This::FaceHandle; + static ValueHandle toHandle(const Mesh* const _mesh, This::HalfedgeHandle _heh) { return static_cast(_mesh)->face_handle(_mesh->opposite_halfedge_handle(_heh)); } + }; /** * Enumerate adjacent faces in a counter clockwise fashion. */ - typedef Iterators::GenericCirculatorT_DEPRECATED::toOppositeFaceHandle> - FaceFaceIter; - typedef Iterators::GenericCirculatorT::toOppositeFaceHandle> FaceFaceCCWIter; + typedef Iterators::GenericCirculatorT_DEPRECATED FaceFaceIter; + typedef Iterators::GenericCirculatorT FaceFaceCCWIter; /** * Enumerate adjacent faces in a clockwise fashion. */ - typedef Iterators::GenericCirculatorT::toOppositeFaceHandle, false> - FaceFaceCWIter; + typedef Iterators::GenericCirculatorT FaceFaceCWIter; typedef FaceVertexIter ConstFaceVertexIter; typedef FaceVertexCWIter ConstFaceVertexCWIter; @@ -401,8 +481,7 @@ public: //@{ /// Add a new vertex - inline VertexHandle add_vertex() - { return new_vertex(); } + inline SmartVertexHandle add_vertex(); /** \brief Add and connect a new face * @@ -411,7 +490,16 @@ public: * * @param _vhandles sorted list of vertex handles (also defines order in which the vertices are added to the face) */ - FaceHandle add_face(const std::vector& _vhandles); + SmartFaceHandle add_face(const std::vector& _vhandles); + + /** \brief Add and connect a new face + * + * Create a new face consisting of the vertices provided by the vertex handle vector. + * (The vertices have to be already added to the mesh by add_vertex) + * + * @param _vhandles sorted list of vertex handles (also defines order in which the vertices are added to the face) + */ + SmartFaceHandle add_face(const std::vector& _vhandles); /** \brief Add and connect a new face @@ -423,7 +511,7 @@ public: * @param _vh1 Second vertex handle * @param _vh2 Third vertex handle */ - FaceHandle add_face(VertexHandle _vh0, VertexHandle _vh1, VertexHandle _vh2); + SmartFaceHandle add_face(VertexHandle _vh0, VertexHandle _vh1, VertexHandle _vh2); /** \brief Add and connect a new face * @@ -435,7 +523,7 @@ public: * @param _vh2 Third vertex handle * @param _vh3 Fourth vertex handle */ - FaceHandle add_face(VertexHandle _vh0, VertexHandle _vh1, VertexHandle _vh2, VertexHandle _vh3); + SmartFaceHandle add_face(VertexHandle _vh0, VertexHandle _vh1, VertexHandle _vh2, VertexHandle _vh3); /** \brief Add and connect a new face * @@ -445,7 +533,7 @@ public: * @param _vhandles pointer to a sorted list of vertex handles (also defines order in which the vertices are added to the face) * @param _vhs_size number of vertex handles in the array */ - FaceHandle add_face(const VertexHandle* _vhandles, size_t _vhs_size); + SmartFaceHandle add_face(const VertexHandle* _vhandles, size_t _vhs_size); //@} @@ -488,6 +576,44 @@ public: */ void delete_face(FaceHandle _fh, bool _delete_isolated_vertices=true); + + //@} + + /** \name Navigation with smart handles to allow usage of old-style navigation with smart handles + */ + //@{ + + using ArrayKernel::next_halfedge_handle; + using ArrayKernel::prev_halfedge_handle; + using ArrayKernel::opposite_halfedge_handle; + using ArrayKernel::ccw_rotated_halfedge_handle; + using ArrayKernel::cw_rotated_halfedge_handle; + + inline SmartHalfedgeHandle next_halfedge_handle (SmartHalfedgeHandle _heh) const; + inline SmartHalfedgeHandle prev_halfedge_handle (SmartHalfedgeHandle _heh) const; + inline SmartHalfedgeHandle opposite_halfedge_handle (SmartHalfedgeHandle _heh) const; + inline SmartHalfedgeHandle ccw_rotated_halfedge_handle(SmartHalfedgeHandle _heh) const; + inline SmartHalfedgeHandle cw_rotated_halfedge_handle (SmartHalfedgeHandle _heh) const; + + using ArrayKernel::s_halfedge_handle; + using ArrayKernel::s_edge_handle; + + static SmartHalfedgeHandle s_halfedge_handle(SmartEdgeHandle _eh, unsigned int _i); + static SmartEdgeHandle s_edge_handle(SmartHalfedgeHandle _heh); + + using ArrayKernel::halfedge_handle; + using ArrayKernel::edge_handle; + using ArrayKernel::face_handle; + + inline SmartHalfedgeHandle halfedge_handle(SmartEdgeHandle _eh, unsigned int _i) const; + inline SmartHalfedgeHandle halfedge_handle(SmartFaceHandle _fh) const; + inline SmartHalfedgeHandle halfedge_handle(SmartVertexHandle _vh) const; + inline SmartEdgeHandle edge_handle(SmartHalfedgeHandle _heh) const; + inline SmartFaceHandle face_handle(SmartHalfedgeHandle _heh) const; + + /// returns the face handle of the opposite halfedge + inline SmartFaceHandle opposite_face_handle(HalfedgeHandle _heh) const; + //@} /** \name Begin and end iterators @@ -537,32 +663,24 @@ public: //@{ /// Begin iterator for vertices - VertexIter vertices_sbegin() - { return VertexIter(*this, VertexHandle(0), true); } + VertexIter vertices_sbegin(); /// Const begin iterator for vertices - ConstVertexIter vertices_sbegin() const - { return ConstVertexIter(*this, VertexHandle(0), true); } + ConstVertexIter vertices_sbegin() const; /// Begin iterator for halfedges - HalfedgeIter halfedges_sbegin() - { return HalfedgeIter(*this, HalfedgeHandle(0), true); } + HalfedgeIter halfedges_sbegin(); /// Const begin iterator for halfedges - ConstHalfedgeIter halfedges_sbegin() const - { return ConstHalfedgeIter(*this, HalfedgeHandle(0), true); } + ConstHalfedgeIter halfedges_sbegin() const; /// Begin iterator for edges - EdgeIter edges_sbegin() - { return EdgeIter(*this, EdgeHandle(0), true); } + EdgeIter edges_sbegin(); /// Const begin iterator for edges - ConstEdgeIter edges_sbegin() const - { return ConstEdgeIter(*this, EdgeHandle(0), true); } + ConstEdgeIter edges_sbegin() const; /// Begin iterator for faces - FaceIter faces_sbegin() - { return FaceIter(*this, FaceHandle(0), true); } + FaceIter faces_sbegin(); /// Const begin iterator for faces - ConstFaceIter faces_sbegin() const - { return ConstFaceIter(*this, FaceHandle(0), true); } + ConstFaceIter faces_sbegin() const; //@} @@ -573,760 +691,599 @@ public: //@{ /// vertex - vertex circulator - VertexVertexIter vv_iter(VertexHandle _vh) - { return VertexVertexIter(*this, _vh); } + VertexVertexIter vv_iter(VertexHandle _vh); /// vertex - vertex circulator cw - VertexVertexCWIter vv_cwiter(VertexHandle _vh) - { return VertexVertexCWIter(*this, _vh); } + VertexVertexCWIter vv_cwiter(VertexHandle _vh); /// vertex - vertex circulator ccw - VertexVertexCCWIter vv_ccwiter(VertexHandle _vh) - { return VertexVertexCCWIter(*this, _vh); } + VertexVertexCCWIter vv_ccwiter(VertexHandle _vh); /// vertex - incoming halfedge circulator - VertexIHalfedgeIter vih_iter(VertexHandle _vh) - { return VertexIHalfedgeIter(*this, _vh); } + VertexIHalfedgeIter vih_iter(VertexHandle _vh); /// vertex - incoming halfedge circulator cw - VertexIHalfedgeCWIter vih_cwiter(VertexHandle _vh) - { return VertexIHalfedgeCWIter(*this, _vh); } + VertexIHalfedgeCWIter vih_cwiter(VertexHandle _vh); /// vertex - incoming halfedge circulator ccw - VertexIHalfedgeCCWIter vih_ccwiter(VertexHandle _vh) - { return VertexIHalfedgeCCWIter(*this, _vh); } + VertexIHalfedgeCCWIter vih_ccwiter(VertexHandle _vh); /// vertex - outgoing halfedge circulator - VertexOHalfedgeIter voh_iter(VertexHandle _vh) - { return VertexOHalfedgeIter(*this, _vh); } + VertexOHalfedgeIter voh_iter(VertexHandle _vh); /// vertex - outgoing halfedge circulator cw - VertexOHalfedgeCWIter voh_cwiter(VertexHandle _vh) - { return VertexOHalfedgeCWIter(*this, _vh); } + VertexOHalfedgeCWIter voh_cwiter(VertexHandle _vh); /// vertex - outgoing halfedge circulator ccw - VertexOHalfedgeCCWIter voh_ccwiter(VertexHandle _vh) - { return VertexOHalfedgeCCWIter(*this, _vh); } + VertexOHalfedgeCCWIter voh_ccwiter(VertexHandle _vh); /// vertex - edge circulator - VertexEdgeIter ve_iter(VertexHandle _vh) - { return VertexEdgeIter(*this, _vh); } + VertexEdgeIter ve_iter(VertexHandle _vh); /// vertex - edge circulator cw - VertexEdgeCWIter ve_cwiter(VertexHandle _vh) - { return VertexEdgeCWIter(*this, _vh); } + VertexEdgeCWIter ve_cwiter(VertexHandle _vh); /// vertex - edge circulator ccw - VertexEdgeCCWIter ve_ccwiter(VertexHandle _vh) - { return VertexEdgeCCWIter(*this, _vh); } + VertexEdgeCCWIter ve_ccwiter(VertexHandle _vh); /// vertex - face circulator - VertexFaceIter vf_iter(VertexHandle _vh) - { return VertexFaceIter(*this, _vh); } + VertexFaceIter vf_iter(VertexHandle _vh); /// vertex - face circulator cw - VertexFaceCWIter vf_cwiter(VertexHandle _vh) - { return VertexFaceCWIter(*this, _vh); } + VertexFaceCWIter vf_cwiter(VertexHandle _vh); /// vertex - face circulator ccw - VertexFaceCCWIter vf_ccwiter(VertexHandle _vh) - { return VertexFaceCCWIter(*this, _vh); } + VertexFaceCCWIter vf_ccwiter(VertexHandle _vh); /// const vertex circulator - ConstVertexVertexIter cvv_iter(VertexHandle _vh) const - { return ConstVertexVertexIter(*this, _vh); } + ConstVertexVertexIter cvv_iter(VertexHandle _vh) const; /// const vertex circulator cw - ConstVertexVertexCWIter cvv_cwiter(VertexHandle _vh) const - { return ConstVertexVertexCWIter(*this, _vh); } + ConstVertexVertexCWIter cvv_cwiter(VertexHandle _vh) const; /// const vertex circulator ccw - ConstVertexVertexCCWIter cvv_ccwiter(VertexHandle _vh) const - { return ConstVertexVertexCCWIter(*this, _vh); } + ConstVertexVertexCCWIter cvv_ccwiter(VertexHandle _vh) const; /// const vertex - incoming halfedge circulator - ConstVertexIHalfedgeIter cvih_iter(VertexHandle _vh) const - { return ConstVertexIHalfedgeIter(*this, _vh); } + ConstVertexIHalfedgeIter cvih_iter(VertexHandle _vh) const; /// const vertex - incoming halfedge circulator cw - ConstVertexIHalfedgeCWIter cvih_cwiter(VertexHandle _vh) const - { return ConstVertexIHalfedgeCWIter(*this, _vh); } + ConstVertexIHalfedgeCWIter cvih_cwiter(VertexHandle _vh) const; /// const vertex - incoming halfedge circulator ccw - ConstVertexIHalfedgeCCWIter cvih_ccwiter(VertexHandle _vh) const - { return ConstVertexIHalfedgeCCWIter(*this, _vh); } + ConstVertexIHalfedgeCCWIter cvih_ccwiter(VertexHandle _vh) const; /// const vertex - outgoing halfedge circulator - ConstVertexOHalfedgeIter cvoh_iter(VertexHandle _vh) const - { return ConstVertexOHalfedgeIter(*this, _vh); } + ConstVertexOHalfedgeIter cvoh_iter(VertexHandle _vh) const; /// const vertex - outgoing halfedge circulator cw - ConstVertexOHalfedgeCWIter cvoh_cwiter(VertexHandle _vh) const - { return ConstVertexOHalfedgeCWIter(*this, _vh); } + ConstVertexOHalfedgeCWIter cvoh_cwiter(VertexHandle _vh) const; /// const vertex - outgoing halfedge circulator ccw - ConstVertexOHalfedgeCCWIter cvoh_ccwiter(VertexHandle _vh) const - { return ConstVertexOHalfedgeCCWIter(*this, _vh); } + ConstVertexOHalfedgeCCWIter cvoh_ccwiter(VertexHandle _vh) const; /// const vertex - edge circulator - ConstVertexEdgeIter cve_iter(VertexHandle _vh) const - { return ConstVertexEdgeIter(*this, _vh); } + ConstVertexEdgeIter cve_iter(VertexHandle _vh) const; /// const vertex - edge circulator cw - ConstVertexEdgeCWIter cve_cwiter(VertexHandle _vh) const - { return ConstVertexEdgeCWIter(*this, _vh); } + ConstVertexEdgeCWIter cve_cwiter(VertexHandle _vh) const; /// const vertex - edge circulator ccw - ConstVertexEdgeCCWIter cve_ccwiter(VertexHandle _vh) const - { return ConstVertexEdgeCCWIter(*this, _vh); } + ConstVertexEdgeCCWIter cve_ccwiter(VertexHandle _vh) const; /// const vertex - face circulator - ConstVertexFaceIter cvf_iter(VertexHandle _vh) const - { return ConstVertexFaceIter(*this, _vh); } + ConstVertexFaceIter cvf_iter(VertexHandle _vh) const; /// const vertex - face circulator cw - ConstVertexFaceCWIter cvf_cwiter(VertexHandle _vh) const - { return ConstVertexFaceCWIter(*this, _vh); } + ConstVertexFaceCWIter cvf_cwiter(VertexHandle _vh) const; /// const vertex - face circulator ccw - ConstVertexFaceCCWIter cvf_ccwiter(VertexHandle _vh) const - { return ConstVertexFaceCCWIter(*this, _vh); } + ConstVertexFaceCCWIter cvf_ccwiter(VertexHandle _vh) const; /// face - vertex circulator - FaceVertexIter fv_iter(FaceHandle _fh) - { return FaceVertexIter(*this, _fh); } + FaceVertexIter fv_iter(FaceHandle _fh); /// face - vertex circulator cw - FaceVertexCWIter fv_cwiter(FaceHandle _fh) - { return FaceVertexCWIter(*this, _fh); } + FaceVertexCWIter fv_cwiter(FaceHandle _fh); /// face - vertex circulator ccw - FaceVertexCCWIter fv_ccwiter(FaceHandle _fh) - { return FaceVertexCCWIter(*this, _fh); } + FaceVertexCCWIter fv_ccwiter(FaceHandle _fh); /// face - halfedge circulator - FaceHalfedgeIter fh_iter(FaceHandle _fh) - { return FaceHalfedgeIter(*this, _fh); } + FaceHalfedgeIter fh_iter(FaceHandle _fh); /// face - halfedge circulator cw - FaceHalfedgeCWIter fh_cwiter(FaceHandle _fh) - { return FaceHalfedgeCWIter(*this, _fh); } + FaceHalfedgeCWIter fh_cwiter(FaceHandle _fh); /// face - halfedge circulator ccw - FaceHalfedgeCCWIter fh_ccwiter(FaceHandle _fh) - { return FaceHalfedgeCCWIter(*this, _fh); } + FaceHalfedgeCCWIter fh_ccwiter(FaceHandle _fh); /// face - edge circulator - FaceEdgeIter fe_iter(FaceHandle _fh) - { return FaceEdgeIter(*this, _fh); } + FaceEdgeIter fe_iter(FaceHandle _fh); /// face - edge circulator cw - FaceEdgeCWIter fe_cwiter(FaceHandle _fh) - { return FaceEdgeCWIter(*this, _fh); } + FaceEdgeCWIter fe_cwiter(FaceHandle _fh); /// face - edge circulator ccw - FaceEdgeCCWIter fe_ccwiter(FaceHandle _fh) - { return FaceEdgeCCWIter(*this, _fh); } + FaceEdgeCCWIter fe_ccwiter(FaceHandle _fh); /// face - face circulator - FaceFaceIter ff_iter(FaceHandle _fh) - { return FaceFaceIter(*this, _fh); } + FaceFaceIter ff_iter(FaceHandle _fh); /// face - face circulator cw - FaceFaceCWIter ff_cwiter(FaceHandle _fh) - { return FaceFaceCWIter(*this, _fh); } + FaceFaceCWIter ff_cwiter(FaceHandle _fh); /// face - face circulator ccw - FaceFaceCCWIter ff_ccwiter(FaceHandle _fh) - { return FaceFaceCCWIter(*this, _fh); } + FaceFaceCCWIter ff_ccwiter(FaceHandle _fh); /// const face - vertex circulator - ConstFaceVertexIter cfv_iter(FaceHandle _fh) const - { return ConstFaceVertexIter(*this, _fh); } + ConstFaceVertexIter cfv_iter(FaceHandle _fh) const; /// const face - vertex circulator cw - ConstFaceVertexCWIter cfv_cwiter(FaceHandle _fh) const - { return ConstFaceVertexCWIter(*this, _fh); } + ConstFaceVertexCWIter cfv_cwiter(FaceHandle _fh) const; /// const face - vertex circulator ccw - ConstFaceVertexCCWIter cfv_ccwiter(FaceHandle _fh) const - { return ConstFaceVertexCCWIter(*this, _fh); } + ConstFaceVertexCCWIter cfv_ccwiter(FaceHandle _fh) const; /// const face - halfedge circulator - ConstFaceHalfedgeIter cfh_iter(FaceHandle _fh) const - { return ConstFaceHalfedgeIter(*this, _fh); } + ConstFaceHalfedgeIter cfh_iter(FaceHandle _fh) const; /// const face - halfedge circulator cw - ConstFaceHalfedgeCWIter cfh_cwiter(FaceHandle _fh) const - { return ConstFaceHalfedgeCWIter(*this, _fh); } + ConstFaceHalfedgeCWIter cfh_cwiter(FaceHandle _fh) const; /// const face - halfedge circulator ccw - ConstFaceHalfedgeCCWIter cfh_ccwiter(FaceHandle _fh) const - { return ConstFaceHalfedgeCCWIter(*this, _fh); } + ConstFaceHalfedgeCCWIter cfh_ccwiter(FaceHandle _fh) const; /// const face - edge circulator - ConstFaceEdgeIter cfe_iter(FaceHandle _fh) const - { return ConstFaceEdgeIter(*this, _fh); } + ConstFaceEdgeIter cfe_iter(FaceHandle _fh) const; /// const face - edge circulator cw - ConstFaceEdgeCWIter cfe_cwiter(FaceHandle _fh) const - { return ConstFaceEdgeCWIter(*this, _fh); } + ConstFaceEdgeCWIter cfe_cwiter(FaceHandle _fh) const; /// const face - edge circulator ccw - ConstFaceEdgeCCWIter cfe_ccwiter(FaceHandle _fh) const - { return ConstFaceEdgeCCWIter(*this, _fh); } + ConstFaceEdgeCCWIter cfe_ccwiter(FaceHandle _fh) const; /// const face - face circulator - ConstFaceFaceIter cff_iter(FaceHandle _fh) const - { return ConstFaceFaceIter(*this, _fh); } + ConstFaceFaceIter cff_iter(FaceHandle _fh) const; /// const face - face circulator cw - ConstFaceFaceCWIter cff_cwiter(FaceHandle _fh) const - { return ConstFaceFaceCWIter(*this, _fh); } + ConstFaceFaceCWIter cff_cwiter(FaceHandle _fh) const; /// const face - face circulator - ConstFaceFaceCCWIter cff_ccwiter(FaceHandle _fh) const - { return ConstFaceFaceCCWIter(*this, _fh); } + ConstFaceFaceCCWIter cff_ccwiter(FaceHandle _fh) const; // 'begin' circulators /// vertex - vertex circulator - VertexVertexIter vv_begin(VertexHandle _vh) - { return VertexVertexIter(*this, _vh); } + VertexVertexIter vv_begin(VertexHandle _vh); /// vertex - vertex circulator cw - VertexVertexCWIter vv_cwbegin(VertexHandle _vh) - { return VertexVertexCWIter(*this, _vh); } + VertexVertexCWIter vv_cwbegin(VertexHandle _vh); /// vertex - vertex circulator ccw - VertexVertexCCWIter vv_ccwbegin(VertexHandle _vh) - { return VertexVertexCCWIter(*this, _vh); } + VertexVertexCCWIter vv_ccwbegin(VertexHandle _vh); /// vertex - incoming halfedge circulator - VertexIHalfedgeIter vih_begin(VertexHandle _vh) - { return VertexIHalfedgeIter(*this, _vh); } + VertexIHalfedgeIter vih_begin(VertexHandle _vh); /// vertex - incoming halfedge circulator cw - VertexIHalfedgeCWIter vih_cwbegin(VertexHandle _vh) - { return VertexIHalfedgeCWIter(*this, _vh); } + VertexIHalfedgeCWIter vih_cwbegin(VertexHandle _vh); /// vertex - incoming halfedge circulator ccw - VertexIHalfedgeCCWIter vih_ccwbegin(VertexHandle _vh) - { return VertexIHalfedgeCCWIter(*this, _vh); } + VertexIHalfedgeCCWIter vih_ccwbegin(VertexHandle _vh); /// vertex - outgoing halfedge circulator - VertexOHalfedgeIter voh_begin(VertexHandle _vh) - { return VertexOHalfedgeIter(*this, _vh); } + VertexOHalfedgeIter voh_begin(VertexHandle _vh); /// vertex - outgoing halfedge circulator cw - VertexOHalfedgeCWIter voh_cwbegin(VertexHandle _vh) - { return VertexOHalfedgeCWIter(*this, _vh); } + VertexOHalfedgeCWIter voh_cwbegin(VertexHandle _vh); /// vertex - outgoing halfedge circulator ccw - VertexOHalfedgeCCWIter voh_ccwbegin(VertexHandle _vh) - { return VertexOHalfedgeCCWIter(*this, _vh); } + VertexOHalfedgeCCWIter voh_ccwbegin(VertexHandle _vh); /// vertex - edge circulator - VertexEdgeIter ve_begin(VertexHandle _vh) - { return VertexEdgeIter(*this, _vh); } + VertexEdgeIter ve_begin(VertexHandle _vh); /// vertex - edge circulator cw - VertexEdgeCWIter ve_cwbegin(VertexHandle _vh) - { return VertexEdgeCWIter(*this, _vh); } + VertexEdgeCWIter ve_cwbegin(VertexHandle _vh); /// vertex - edge circulator ccw - VertexEdgeCCWIter ve_ccwbegin(VertexHandle _vh) - { return VertexEdgeCCWIter(*this, _vh); } + VertexEdgeCCWIter ve_ccwbegin(VertexHandle _vh); /// vertex - face circulator - VertexFaceIter vf_begin(VertexHandle _vh) - { return VertexFaceIter(*this, _vh); } + VertexFaceIter vf_begin(VertexHandle _vh); /// vertex - face circulator cw - VertexFaceCWIter vf_cwbegin(VertexHandle _vh) - { return VertexFaceCWIter(*this, _vh); } + VertexFaceCWIter vf_cwbegin(VertexHandle _vh); /// vertex - face circulator ccw - VertexFaceCCWIter vf_ccwbegin(VertexHandle _vh) - { return VertexFaceCCWIter(*this, _vh); } + VertexFaceCCWIter vf_ccwbegin(VertexHandle _vh); /// const vertex circulator - ConstVertexVertexIter cvv_begin(VertexHandle _vh) const - { return ConstVertexVertexIter(*this, _vh); } + ConstVertexVertexIter cvv_begin(VertexHandle _vh) const; /// const vertex circulator cw - ConstVertexVertexCWIter cvv_cwbegin(VertexHandle _vh) const - { return ConstVertexVertexCWIter(*this, _vh); } + ConstVertexVertexCWIter cvv_cwbegin(VertexHandle _vh) const; /// const vertex circulator ccw - ConstVertexVertexCCWIter cvv_ccwbegin(VertexHandle _vh) const - { return ConstVertexVertexCCWIter(*this, _vh); } + ConstVertexVertexCCWIter cvv_ccwbegin(VertexHandle _vh) const; /// const vertex - incoming halfedge circulator - ConstVertexIHalfedgeIter cvih_begin(VertexHandle _vh) const - { return ConstVertexIHalfedgeIter(*this, _vh); } + ConstVertexIHalfedgeIter cvih_begin(VertexHandle _vh) const; /// const vertex - incoming halfedge circulator cw - ConstVertexIHalfedgeCWIter cvih_cwbegin(VertexHandle _vh) const - { return ConstVertexIHalfedgeCWIter(*this, _vh); } + ConstVertexIHalfedgeCWIter cvih_cwbegin(VertexHandle _vh) const; /// const vertex - incoming halfedge circulator ccw - ConstVertexIHalfedgeCCWIter cvih_ccwbegin(VertexHandle _vh) const - { return ConstVertexIHalfedgeCCWIter(*this, _vh); } + ConstVertexIHalfedgeCCWIter cvih_ccwbegin(VertexHandle _vh) const; /// const vertex - outgoing halfedge circulator - ConstVertexOHalfedgeIter cvoh_begin(VertexHandle _vh) const - { return ConstVertexOHalfedgeIter(*this, _vh); } + ConstVertexOHalfedgeIter cvoh_begin(VertexHandle _vh) const; /// const vertex - outgoing halfedge circulator cw - ConstVertexOHalfedgeCWIter cvoh_cwbegin(VertexHandle _vh) const - { return ConstVertexOHalfedgeCWIter(*this, _vh); } + ConstVertexOHalfedgeCWIter cvoh_cwbegin(VertexHandle _vh) const; /// const vertex - outgoing halfedge circulator ccw - ConstVertexOHalfedgeCCWIter cvoh_ccwbegin(VertexHandle _vh) const - { return ConstVertexOHalfedgeCCWIter(*this, _vh); } + ConstVertexOHalfedgeCCWIter cvoh_ccwbegin(VertexHandle _vh) const; /// const vertex - edge circulator - ConstVertexEdgeIter cve_begin(VertexHandle _vh) const - { return ConstVertexEdgeIter(*this, _vh); } + ConstVertexEdgeIter cve_begin(VertexHandle _vh) const; /// const vertex - edge circulator cw - ConstVertexEdgeCWIter cve_cwbegin(VertexHandle _vh) const - { return ConstVertexEdgeCWIter(*this, _vh); } + ConstVertexEdgeCWIter cve_cwbegin(VertexHandle _vh) const; /// const vertex - edge circulator ccw - ConstVertexEdgeCCWIter cve_ccwbegin(VertexHandle _vh) const - { return ConstVertexEdgeCCWIter(*this, _vh); } + ConstVertexEdgeCCWIter cve_ccwbegin(VertexHandle _vh) const; /// const vertex - face circulator - ConstVertexFaceIter cvf_begin(VertexHandle _vh) const - { return ConstVertexFaceIter(*this, _vh); } + ConstVertexFaceIter cvf_begin(VertexHandle _vh) const; /// const vertex - face circulator cw - ConstVertexFaceCWIter cvf_cwbegin(VertexHandle _vh) const - { return ConstVertexFaceCWIter(*this, _vh); } + ConstVertexFaceCWIter cvf_cwbegin(VertexHandle _vh) const; /// const vertex - face circulator ccw - ConstVertexFaceCCWIter cvf_ccwbegin(VertexHandle _vh) const - { return ConstVertexFaceCCWIter(*this, _vh); } + ConstVertexFaceCCWIter cvf_ccwbegin(VertexHandle _vh) const; /// face - vertex circulator - FaceVertexIter fv_begin(FaceHandle _fh) - { return FaceVertexIter(*this, _fh); } + FaceVertexIter fv_begin(FaceHandle _fh); /// face - vertex circulator cw - FaceVertexCWIter fv_cwbegin(FaceHandle _fh) - { return FaceVertexCWIter(*this, _fh); } + FaceVertexCWIter fv_cwbegin(FaceHandle _fh); /// face - vertex circulator ccw - FaceVertexCCWIter fv_ccwbegin(FaceHandle _fh) - { return FaceVertexCCWIter(*this, _fh); } + FaceVertexCCWIter fv_ccwbegin(FaceHandle _fh); /// face - halfedge circulator - FaceHalfedgeIter fh_begin(FaceHandle _fh) - { return FaceHalfedgeIter(*this, _fh); } + FaceHalfedgeIter fh_begin(FaceHandle _fh); /// face - halfedge circulator cw - FaceHalfedgeCWIter fh_cwbegin(FaceHandle _fh) - { return FaceHalfedgeCWIter(*this, _fh); } + FaceHalfedgeCWIter fh_cwbegin(FaceHandle _fh); /// face - halfedge circulator ccw - FaceHalfedgeCCWIter fh_ccwbegin(FaceHandle _fh) - { return FaceHalfedgeCCWIter(*this, _fh); } + FaceHalfedgeCCWIter fh_ccwbegin(FaceHandle _fh); /// face - edge circulator - FaceEdgeIter fe_begin(FaceHandle _fh) - { return FaceEdgeIter(*this, _fh); } + FaceEdgeIter fe_begin(FaceHandle _fh); /// face - edge circulator cw - FaceEdgeCWIter fe_cwbegin(FaceHandle _fh) - { return FaceEdgeCWIter(*this, _fh); } + FaceEdgeCWIter fe_cwbegin(FaceHandle _fh); /// face - edge circulator ccw - FaceEdgeCCWIter fe_ccwbegin(FaceHandle _fh) - { return FaceEdgeCCWIter(*this, _fh); } + FaceEdgeCCWIter fe_ccwbegin(FaceHandle _fh); /// face - face circulator - FaceFaceIter ff_begin(FaceHandle _fh) - { return FaceFaceIter(*this, _fh); } + FaceFaceIter ff_begin(FaceHandle _fh); /// face - face circulator cw - FaceFaceCWIter ff_cwbegin(FaceHandle _fh) - { return FaceFaceCWIter(*this, _fh); } + FaceFaceCWIter ff_cwbegin(FaceHandle _fh); /// face - face circulator ccw - FaceFaceCCWIter ff_ccwbegin(FaceHandle _fh) - { return FaceFaceCCWIter(*this, _fh); } + FaceFaceCCWIter ff_ccwbegin(FaceHandle _fh); /// halfedge circulator - HalfedgeLoopIter hl_begin(HalfedgeHandle _heh) - { return HalfedgeLoopIter(*this, _heh); } + HalfedgeLoopIter hl_begin(HalfedgeHandle _heh); /// halfedge circulator - HalfedgeLoopCWIter hl_cwbegin(HalfedgeHandle _heh) - { return HalfedgeLoopCWIter(*this, _heh); } + HalfedgeLoopCWIter hl_cwbegin(HalfedgeHandle _heh); /// halfedge circulator ccw - HalfedgeLoopCCWIter hl_ccwbegin(HalfedgeHandle _heh) - { return HalfedgeLoopCCWIter(*this, _heh); } + HalfedgeLoopCCWIter hl_ccwbegin(HalfedgeHandle _heh); /// const face - vertex circulator - ConstFaceVertexIter cfv_begin(FaceHandle _fh) const - { return ConstFaceVertexIter(*this, _fh); } + ConstFaceVertexIter cfv_begin(FaceHandle _fh) const; /// const face - vertex circulator cw - ConstFaceVertexCWIter cfv_cwbegin(FaceHandle _fh) const - { return ConstFaceVertexCWIter(*this, _fh); } + ConstFaceVertexCWIter cfv_cwbegin(FaceHandle _fh) const; /// const face - vertex circulator ccw - ConstFaceVertexCCWIter cfv_ccwbegin(FaceHandle _fh) const - { return ConstFaceVertexCCWIter(*this, _fh); } + ConstFaceVertexCCWIter cfv_ccwbegin(FaceHandle _fh) const; /// const face - halfedge circulator - ConstFaceHalfedgeIter cfh_begin(FaceHandle _fh) const - { return ConstFaceHalfedgeIter(*this, _fh); } + ConstFaceHalfedgeIter cfh_begin(FaceHandle _fh) const; /// const face - halfedge circulator cw - ConstFaceHalfedgeCWIter cfh_cwbegin(FaceHandle _fh) const - { return ConstFaceHalfedgeCWIter(*this, _fh); } + ConstFaceHalfedgeCWIter cfh_cwbegin(FaceHandle _fh) const; /// const face - halfedge circulator ccw - ConstFaceHalfedgeCCWIter cfh_ccwbegin(FaceHandle _fh) const - { return ConstFaceHalfedgeCCWIter(*this, _fh); } + ConstFaceHalfedgeCCWIter cfh_ccwbegin(FaceHandle _fh) const; /// const face - edge circulator - ConstFaceEdgeIter cfe_begin(FaceHandle _fh) const - { return ConstFaceEdgeIter(*this, _fh); } + ConstFaceEdgeIter cfe_begin(FaceHandle _fh) const; /// const face - edge circulator cw - ConstFaceEdgeCWIter cfe_cwbegin(FaceHandle _fh) const - { return ConstFaceEdgeCWIter(*this, _fh); } + ConstFaceEdgeCWIter cfe_cwbegin(FaceHandle _fh) const; /// const face - edge circulator ccw - ConstFaceEdgeCCWIter cfe_ccwbegin(FaceHandle _fh) const - { return ConstFaceEdgeCCWIter(*this, _fh); } + ConstFaceEdgeCCWIter cfe_ccwbegin(FaceHandle _fh) const; /// const face - face circulator - ConstFaceFaceIter cff_begin(FaceHandle _fh) const - { return ConstFaceFaceIter(*this, _fh); } + ConstFaceFaceIter cff_begin(FaceHandle _fh) const; /// const face - face circulator cw - ConstFaceFaceCWIter cff_cwbegin(FaceHandle _fh) const - { return ConstFaceFaceCWIter(*this, _fh); } + ConstFaceFaceCWIter cff_cwbegin(FaceHandle _fh) const; /// const face - face circulator ccw - ConstFaceFaceCCWIter cff_ccwbegin(FaceHandle _fh) const - { return ConstFaceFaceCCWIter(*this, _fh); } + ConstFaceFaceCCWIter cff_ccwbegin(FaceHandle _fh) const; /// const halfedge circulator - ConstHalfedgeLoopIter chl_begin(HalfedgeHandle _heh) const - { return ConstHalfedgeLoopIter(*this, _heh); } + ConstHalfedgeLoopIter chl_begin(HalfedgeHandle _heh) const; /// const halfedge circulator cw - ConstHalfedgeLoopCWIter chl_cwbegin(HalfedgeHandle _heh) const - { return ConstHalfedgeLoopCWIter(*this, _heh); } + ConstHalfedgeLoopCWIter chl_cwbegin(HalfedgeHandle _heh) const; /// const halfedge circulator ccw - ConstHalfedgeLoopCCWIter chl_ccwbegin(HalfedgeHandle _heh) const - { return ConstHalfedgeLoopCCWIter(*this, _heh); } + ConstHalfedgeLoopCCWIter chl_ccwbegin(HalfedgeHandle _heh) const; // 'end' circulators /// vertex - vertex circulator - VertexVertexIter vv_end(VertexHandle _vh) - { return VertexVertexIter(*this, _vh, true); } + VertexVertexIter vv_end(VertexHandle _vh); /// vertex - vertex circulator cw - VertexVertexCWIter vv_cwend(VertexHandle _vh) - { return VertexVertexCWIter(*this, _vh, true); } + VertexVertexCWIter vv_cwend(VertexHandle _vh); /// vertex - vertex circulator ccw - VertexVertexCCWIter vv_ccwend(VertexHandle _vh) - { return VertexVertexCCWIter(*this, _vh, true); } + VertexVertexCCWIter vv_ccwend(VertexHandle _vh); /// vertex - incoming halfedge circulator - VertexIHalfedgeIter vih_end(VertexHandle _vh) - { return VertexIHalfedgeIter(*this, _vh, true); } + VertexIHalfedgeIter vih_end(VertexHandle _vh); /// vertex - incoming halfedge circulator cw - VertexIHalfedgeCWIter vih_cwend(VertexHandle _vh) - { return VertexIHalfedgeCWIter(*this, _vh, true); } + VertexIHalfedgeCWIter vih_cwend(VertexHandle _vh); /// vertex - incoming halfedge circulator ccw - VertexIHalfedgeCCWIter vih_ccwend(VertexHandle _vh) - { return VertexIHalfedgeCCWIter(*this, _vh, true); } + VertexIHalfedgeCCWIter vih_ccwend(VertexHandle _vh); /// vertex - outgoing halfedge circulator - VertexOHalfedgeIter voh_end(VertexHandle _vh) - { return VertexOHalfedgeIter(*this, _vh, true); } + VertexOHalfedgeIter voh_end(VertexHandle _vh); /// vertex - outgoing halfedge circulator cw - VertexOHalfedgeCWIter voh_cwend(VertexHandle _vh) - { return VertexOHalfedgeCWIter(*this, _vh, true); } + VertexOHalfedgeCWIter voh_cwend(VertexHandle _vh); /// vertex - outgoing halfedge circulator ccw - VertexOHalfedgeCCWIter voh_ccwend(VertexHandle _vh) - { return VertexOHalfedgeCCWIter(*this, _vh, true); } + VertexOHalfedgeCCWIter voh_ccwend(VertexHandle _vh); /// vertex - edge circulator - VertexEdgeIter ve_end(VertexHandle _vh) - { return VertexEdgeIter(*this, _vh, true); } + VertexEdgeIter ve_end(VertexHandle _vh); /// vertex - edge circulator cw - VertexEdgeCWIter ve_cwend(VertexHandle _vh) - { return VertexEdgeCWIter(*this, _vh, true); } + VertexEdgeCWIter ve_cwend(VertexHandle _vh); /// vertex - edge circulator ccw - VertexEdgeCCWIter ve_ccwend(VertexHandle _vh) - { return VertexEdgeCCWIter(*this, _vh, true); } + VertexEdgeCCWIter ve_ccwend(VertexHandle _vh); /// vertex - face circulator - VertexFaceIter vf_end(VertexHandle _vh) - { return VertexFaceIter(*this, _vh, true); } + VertexFaceIter vf_end(VertexHandle _vh); /// vertex - face circulator cw - VertexFaceCWIter vf_cwend(VertexHandle _vh) - { return VertexFaceCWIter(*this, _vh, true); } + VertexFaceCWIter vf_cwend(VertexHandle _vh); /// vertex - face circulator ccw - VertexFaceCCWIter vf_ccwend(VertexHandle _vh) - { return VertexFaceCCWIter(*this, _vh, true); } + VertexFaceCCWIter vf_ccwend(VertexHandle _vh); /// const vertex circulator - ConstVertexVertexIter cvv_end(VertexHandle _vh) const - { return ConstVertexVertexIter(*this, _vh, true); } + ConstVertexVertexIter cvv_end(VertexHandle _vh) const; /// const vertex circulator cw - ConstVertexVertexCWIter cvv_cwend(VertexHandle _vh) const - { return ConstVertexVertexCWIter(*this, _vh, true); } + ConstVertexVertexCWIter cvv_cwend(VertexHandle _vh) const; /// const vertex circulator ccw - ConstVertexVertexCCWIter cvv_ccwend(VertexHandle _vh) const - { return ConstVertexVertexCCWIter(*this, _vh, true); } + ConstVertexVertexCCWIter cvv_ccwend(VertexHandle _vh) const; /// const vertex - incoming halfedge circulator - ConstVertexIHalfedgeIter cvih_end(VertexHandle _vh) const - { return ConstVertexIHalfedgeIter(*this, _vh, true); } + ConstVertexIHalfedgeIter cvih_end(VertexHandle _vh) const; /// const vertex - incoming halfedge circulator cw - ConstVertexIHalfedgeCWIter cvih_cwend(VertexHandle _vh) const - { return ConstVertexIHalfedgeCWIter(*this, _vh, true); } + ConstVertexIHalfedgeCWIter cvih_cwend(VertexHandle _vh) const; /// const vertex - incoming halfedge circulator ccw - ConstVertexIHalfedgeCCWIter cvih_ccwend(VertexHandle _vh) const - { return ConstVertexIHalfedgeCCWIter(*this, _vh, true); } + ConstVertexIHalfedgeCCWIter cvih_ccwend(VertexHandle _vh) const; /// const vertex - outgoing halfedge circulator - ConstVertexOHalfedgeIter cvoh_end(VertexHandle _vh) const - { return ConstVertexOHalfedgeIter(*this, _vh, true); } + ConstVertexOHalfedgeIter cvoh_end(VertexHandle _vh) const; /// const vertex - outgoing halfedge circulator cw - ConstVertexOHalfedgeCWIter cvoh_cwend(VertexHandle _vh) const - { return ConstVertexOHalfedgeCWIter(*this, _vh, true); } + ConstVertexOHalfedgeCWIter cvoh_cwend(VertexHandle _vh) const; /// const vertex - outgoing halfedge circulator ccw - ConstVertexOHalfedgeCCWIter cvoh_ccwend(VertexHandle _vh) const - { return ConstVertexOHalfedgeCCWIter(*this, _vh, true); } + ConstVertexOHalfedgeCCWIter cvoh_ccwend(VertexHandle _vh) const; /// const vertex - edge circulator - ConstVertexEdgeIter cve_end(VertexHandle _vh) const - { return ConstVertexEdgeIter(*this, _vh, true); } + ConstVertexEdgeIter cve_end(VertexHandle _vh) const; /// const vertex - edge circulator cw - ConstVertexEdgeCWIter cve_cwend(VertexHandle _vh) const - { return ConstVertexEdgeCWIter(*this, _vh, true); } + ConstVertexEdgeCWIter cve_cwend(VertexHandle _vh) const; /// const vertex - edge circulator ccw - ConstVertexEdgeCCWIter cve_ccwend(VertexHandle _vh) const - { return ConstVertexEdgeCCWIter(*this, _vh, true); } + ConstVertexEdgeCCWIter cve_ccwend(VertexHandle _vh) const; /// const vertex - face circulator - ConstVertexFaceIter cvf_end(VertexHandle _vh) const - { return ConstVertexFaceIter(*this, _vh, true); } + ConstVertexFaceIter cvf_end(VertexHandle _vh) const; /// const vertex - face circulator cw - ConstVertexFaceCWIter cvf_cwend(VertexHandle _vh) const - { return ConstVertexFaceCWIter(*this, _vh, true); } + ConstVertexFaceCWIter cvf_cwend(VertexHandle _vh) const; /// const vertex - face circulator ccw - ConstVertexFaceCCWIter cvf_ccwend(VertexHandle _vh) const - { return ConstVertexFaceCCWIter(*this, _vh, true); } + ConstVertexFaceCCWIter cvf_ccwend(VertexHandle _vh) const; /// face - vertex circulator - FaceVertexIter fv_end(FaceHandle _fh) - { return FaceVertexIter(*this, _fh, true); } + FaceVertexIter fv_end(FaceHandle _fh); /// face - vertex circulator cw - FaceVertexCWIter fv_cwend(FaceHandle _fh) - { return FaceVertexCWIter(*this, _fh, true); } + FaceVertexCWIter fv_cwend(FaceHandle _fh); /// face - vertex circulator ccw - FaceVertexCCWIter fv_ccwend(FaceHandle _fh) - { return FaceVertexCCWIter(*this, _fh, true); } + FaceVertexCCWIter fv_ccwend(FaceHandle _fh); /// face - halfedge circulator - FaceHalfedgeIter fh_end(FaceHandle _fh) - { return FaceHalfedgeIter(*this, _fh, true); } + FaceHalfedgeIter fh_end(FaceHandle _fh); /// face - halfedge circulator cw - FaceHalfedgeCWIter fh_cwend(FaceHandle _fh) - { return FaceHalfedgeCWIter(*this, _fh, true); } + FaceHalfedgeCWIter fh_cwend(FaceHandle _fh); /// face - halfedge circulator ccw - FaceHalfedgeCCWIter fh_ccwend(FaceHandle _fh) - { return FaceHalfedgeCCWIter(*this, _fh, true); } + FaceHalfedgeCCWIter fh_ccwend(FaceHandle _fh); /// face - edge circulator - FaceEdgeIter fe_end(FaceHandle _fh) - { return FaceEdgeIter(*this, _fh, true); } + FaceEdgeIter fe_end(FaceHandle _fh); /// face - edge circulator cw - FaceEdgeCWIter fe_cwend(FaceHandle _fh) - { return FaceEdgeCWIter(*this, _fh, true); } + FaceEdgeCWIter fe_cwend(FaceHandle _fh); /// face - edge circulator ccw - FaceEdgeCCWIter fe_ccwend(FaceHandle _fh) - { return FaceEdgeCCWIter(*this, _fh, true); } + FaceEdgeCCWIter fe_ccwend(FaceHandle _fh); /// face - face circulator - FaceFaceIter ff_end(FaceHandle _fh) - { return FaceFaceIter(*this, _fh, true); } + FaceFaceIter ff_end(FaceHandle _fh); /// face - face circulator cw - FaceFaceCWIter ff_cwend(FaceHandle _fh) - { return FaceFaceCWIter(*this, _fh, true); } + FaceFaceCWIter ff_cwend(FaceHandle _fh); /// face - face circulator ccw - FaceFaceCCWIter ff_ccwend(FaceHandle _fh) - { return FaceFaceCCWIter(*this, _fh, true); } + FaceFaceCCWIter ff_ccwend(FaceHandle _fh); /// face - face circulator - HalfedgeLoopIter hl_end(HalfedgeHandle _heh) - { return HalfedgeLoopIter(*this, _heh, true); } + HalfedgeLoopIter hl_end(HalfedgeHandle _heh); /// face - face circulator cw - HalfedgeLoopCWIter hl_cwend(HalfedgeHandle _heh) - { return HalfedgeLoopCWIter(*this, _heh, true); } + HalfedgeLoopCWIter hl_cwend(HalfedgeHandle _heh); /// face - face circulator ccw - HalfedgeLoopCCWIter hl_ccwend(HalfedgeHandle _heh) - { return HalfedgeLoopCCWIter(*this, _heh, true); } + HalfedgeLoopCCWIter hl_ccwend(HalfedgeHandle _heh); /// const face - vertex circulator - ConstFaceVertexIter cfv_end(FaceHandle _fh) const - { return ConstFaceVertexIter(*this, _fh, true); } + ConstFaceVertexIter cfv_end(FaceHandle _fh) const; /// const face - vertex circulator cw - ConstFaceVertexCWIter cfv_cwend(FaceHandle _fh) const - { return ConstFaceVertexCWIter(*this, _fh, true); } + ConstFaceVertexCWIter cfv_cwend(FaceHandle _fh) const; /// const face - vertex circulator ccw - ConstFaceVertexCCWIter cfv_ccwend(FaceHandle _fh) const - { return ConstFaceVertexCCWIter(*this, _fh, true); } + ConstFaceVertexCCWIter cfv_ccwend(FaceHandle _fh) const; /// const face - halfedge circulator - ConstFaceHalfedgeIter cfh_end(FaceHandle _fh) const - { return ConstFaceHalfedgeIter(*this, _fh, true); } + ConstFaceHalfedgeIter cfh_end(FaceHandle _fh) const; /// const face - halfedge circulator cw - ConstFaceHalfedgeCWIter cfh_cwend(FaceHandle _fh) const - { return ConstFaceHalfedgeCWIter(*this, _fh, true); } + ConstFaceHalfedgeCWIter cfh_cwend(FaceHandle _fh) const; /// const face - halfedge circulator ccw - ConstFaceHalfedgeCCWIter cfh_ccwend(FaceHandle _fh) const - { return ConstFaceHalfedgeCCWIter(*this, _fh, true); } + ConstFaceHalfedgeCCWIter cfh_ccwend(FaceHandle _fh) const; /// const face - edge circulator - ConstFaceEdgeIter cfe_end(FaceHandle _fh) const - { return ConstFaceEdgeIter(*this, _fh, true); } + ConstFaceEdgeIter cfe_end(FaceHandle _fh) const; /// const face - edge circulator cw - ConstFaceEdgeCWIter cfe_cwend(FaceHandle _fh) const - { return ConstFaceEdgeCWIter(*this, _fh, true); } + ConstFaceEdgeCWIter cfe_cwend(FaceHandle _fh) const; /// const face - edge circulator ccw - ConstFaceEdgeCCWIter cfe_ccwend(FaceHandle _fh) const - { return ConstFaceEdgeCCWIter(*this, _fh, true); } + ConstFaceEdgeCCWIter cfe_ccwend(FaceHandle _fh) const; /// const face - face circulator - ConstFaceFaceIter cff_end(FaceHandle _fh) const - { return ConstFaceFaceIter(*this, _fh, true); } + ConstFaceFaceIter cff_end(FaceHandle _fh) const; /// const face - face circulator - ConstFaceFaceCWIter cff_cwend(FaceHandle _fh) const - { return ConstFaceFaceCWIter(*this, _fh, true); } + ConstFaceFaceCWIter cff_cwend(FaceHandle _fh) const; /// const face - face circulator - ConstFaceFaceCCWIter cff_ccwend(FaceHandle _fh) const - { return ConstFaceFaceCCWIter(*this, _fh, true); } + ConstFaceFaceCCWIter cff_ccwend(FaceHandle _fh) const; /// const face - face circulator - ConstHalfedgeLoopIter chl_end(HalfedgeHandle _heh) const - { return ConstHalfedgeLoopIter(*this, _heh, true); } + ConstHalfedgeLoopIter chl_end(HalfedgeHandle _heh) const; /// const face - face circulator cw - ConstHalfedgeLoopCWIter chl_cwend(HalfedgeHandle _heh) const - { return ConstHalfedgeLoopCWIter(*this, _heh, true); } + ConstHalfedgeLoopCWIter chl_cwend(HalfedgeHandle _heh) const; /// const face - face circulator ccw - ConstHalfedgeLoopCCWIter chl_ccwend(HalfedgeHandle _heh) const - { return ConstHalfedgeLoopCCWIter(*this, _heh, true); } + ConstHalfedgeLoopCCWIter chl_ccwend(HalfedgeHandle _heh) const; //@} /** @name Range based iterators and circulators */ //@{ - /// Generic class for vertex/halfedge/edge/face ranges. - template< - typename CONTAINER_TYPE, - typename ITER_TYPE, - ITER_TYPE (CONTAINER_TYPE::*begin_fn)() const, - ITER_TYPE (CONTAINER_TYPE::*end_fn)() const> - class EntityRange { - public: - typedef ITER_TYPE iterator; - typedef ITER_TYPE const_iterator; - - EntityRange(CONTAINER_TYPE &container) : container_(container) {} - ITER_TYPE begin() const { return (container_.*begin_fn)(); } - ITER_TYPE end() const { return (container_.*end_fn)(); } - - private: - CONTAINER_TYPE &container_; - }; - typedef EntityRange< + typedef EntityRange ConstVertexRange; - typedef EntityRange< + &PolyConnectivity::vertices_end>> ConstVertexRange; + typedef EntityRange> ConstVertexRangeSkipping; + typedef EntityRange ConstHalfedgeRange; - typedef EntityRange< + &PolyConnectivity::halfedges_end>> ConstHalfedgeRange; + typedef EntityRange> ConstHalfedgeRangeSkipping; + typedef EntityRange ConstEdgeRange; - typedef EntityRange< + &PolyConnectivity::edges_end>> ConstEdgeRange; + typedef EntityRange> ConstEdgeRangeSkipping; + typedef EntityRange ConstFaceRange; + &PolyConnectivity::faces_end>> ConstFaceRange; + typedef EntityRange> ConstFaceRangeSkipping; + + + template + struct ElementRange; /** * @return The vertices as a range object suitable - * for C++11 range based for loops. + * for C++11 range based for loops. Will skip deleted vertices. */ - ConstVertexRange vertices() const { return ConstVertexRange(*this); } + ConstVertexRangeSkipping vertices() const; + + /** + * @return The vertices as a range object suitable + * for C++11 range based for loops. Will include deleted vertices. + */ + ConstVertexRange all_vertices() const; /** * @return The halfedges as a range object suitable - * for C++11 range based for loops. + * for C++11 range based for loops. Will skip deleted halfedges. */ - ConstHalfedgeRange halfedges() const { return ConstHalfedgeRange(*this); } + ConstHalfedgeRangeSkipping halfedges() const; /** - * @return The edges as a range object suitabl - * for C++11 range based for loops. + * @return The halfedges as a range object suitable + * for C++11 range based for loops. Will include deleted halfedges. */ - ConstEdgeRange edges() const { return ConstEdgeRange(*this); } + ConstHalfedgeRange all_halfedges() const; + + /** + * @return The edges as a range object suitable + * for C++11 range based for loops. Will skip deleted edges. + */ + ConstEdgeRangeSkipping edges() const; + + /** + * @return The edges as a range object suitable + * for C++11 range based for loops. Will include deleted edges. + */ + ConstEdgeRange all_edges() const; /** * @return The faces as a range object suitable - * for C++11 range based for loops. + * for C++11 range based for loops. Will skip deleted faces. */ - ConstFaceRange faces() const { return ConstFaceRange(*this); } + ConstFaceRangeSkipping faces() const; - /// Generic class for iterator ranges. - template< - typename CONTAINER_TYPE, - typename ITER_TYPE, - typename CENTER_ENTITY_TYPE, - ITER_TYPE (CONTAINER_TYPE::*begin_fn)(CENTER_ENTITY_TYPE) const, - ITER_TYPE (CONTAINER_TYPE::*end_fn)(CENTER_ENTITY_TYPE) const> - class CirculatorRange { - public: - typedef ITER_TYPE iterator; - typedef ITER_TYPE const_iterator; + /** + * @return The faces as a range object suitable + * for C++11 range based for loops. Will include deleted faces. + */ + ConstFaceRange all_faces() const; - CirculatorRange( - const CONTAINER_TYPE &container, - CENTER_ENTITY_TYPE center) : - container_(container), center_(center) {} - ITER_TYPE begin() const { return (container_.*begin_fn)(center_); } - ITER_TYPE end() const { return (container_.*end_fn)(center_); } + /** + * @return The elements corresponding to the template type as a range object suitable + * for C++11 range based for loops. Will skip deleted faces. + */ + template + typename ElementRange::RangeSkipping elements() const; - private: - const CONTAINER_TYPE &container_; - CENTER_ENTITY_TYPE center_; - }; + /** + * @return The elements corresponding to the template type as a range object suitable + * for C++11 range based for loops. Will include deleted faces. + */ + template + typename ElementRange::Range all_elements() const; - typedef CirculatorRange< + + typedef CirculatorRange ConstVertexVertexRange; - typedef CirculatorRange< + &PolyConnectivity::cvv_cwend>> ConstVertexVertexRange; + typedef CirculatorRange ConstVertexIHalfedgeRange; - typedef CirculatorRange< + &PolyConnectivity::cvih_end>> ConstVertexIHalfedgeRange; + typedef CirculatorRange ConstVertexOHalfedgeRange; - typedef CirculatorRange< + &PolyConnectivity::cvoh_end>> ConstVertexOHalfedgeRange; + typedef CirculatorRange ConstVertexEdgeRange; - typedef CirculatorRange< + &PolyConnectivity::cve_end>> ConstVertexEdgeRange; + typedef CirculatorRange ConstVertexFaceRange; - typedef CirculatorRange< + &PolyConnectivity::cvf_end>> ConstVertexFaceRange; + typedef CirculatorRange ConstFaceVertexRange; - typedef CirculatorRange< + &PolyConnectivity::cfv_end>> ConstFaceVertexRange; + typedef CirculatorRange ConstFaceHalfedgeRange; - typedef CirculatorRange< + &PolyConnectivity::cfh_end>> ConstFaceHalfedgeRange; + typedef CirculatorRange ConstFaceEdgeRange; - typedef CirculatorRange< + &PolyConnectivity::cfe_end>> ConstFaceEdgeRange; + typedef CirculatorRange ConstFaceFaceRange; + &PolyConnectivity::cff_end>> ConstFaceFaceRange; /** * @return The vertices adjacent to the specified vertex * as a range object suitable for C++11 range based for loops. */ - ConstVertexVertexRange vv_range(VertexHandle _vh) const { - return ConstVertexVertexRange(*this, _vh); - } + ConstVertexVertexRange vv_range(VertexHandle _vh) const; /** * @return The incoming halfedges incident to the specified vertex * as a range object suitable for C++11 range based for loops. */ - ConstVertexIHalfedgeRange vih_range(VertexHandle _vh) const { - return ConstVertexIHalfedgeRange(*this, _vh); - } + ConstVertexIHalfedgeRange vih_range(VertexHandle _vh) const; /** * @return The outgoing halfedges incident to the specified vertex * as a range object suitable for C++11 range based for loops. */ - ConstVertexOHalfedgeRange voh_range(VertexHandle _vh) const { - return ConstVertexOHalfedgeRange(*this, _vh); - } + ConstVertexOHalfedgeRange voh_range(VertexHandle _vh) const; /** * @return The edges incident to the specified vertex * as a range object suitable for C++11 range based for loops. */ - ConstVertexEdgeRange ve_range(VertexHandle _vh) const { - return ConstVertexEdgeRange(*this, _vh); - } + ConstVertexEdgeRange ve_range(VertexHandle _vh) const ; /** * @return The faces incident to the specified vertex * as a range object suitable for C++11 range based for loops. */ - ConstVertexFaceRange vf_range(VertexHandle _vh) const { - return ConstVertexFaceRange(*this, _vh); - } + ConstVertexFaceRange vf_range(VertexHandle _vh) const; /** * @return The vertices incident to the specified face * as a range object suitable for C++11 range based for loops. */ - ConstFaceVertexRange fv_range(FaceHandle _fh) const { - return ConstFaceVertexRange(*this, _fh); - } + ConstFaceVertexRange fv_range(FaceHandle _fh) const; /** * @return The halfedges incident to the specified face * as a range object suitable for C++11 range based for loops. */ - ConstFaceHalfedgeRange fh_range(FaceHandle _fh) const { - return ConstFaceHalfedgeRange(*this, _fh); - } + ConstFaceHalfedgeRange fh_range(FaceHandle _fh) const; /** * @return The edges incident to the specified face * as a range object suitable for C++11 range based for loops. */ - ConstFaceEdgeRange fe_range(FaceHandle _fh) const { - return ConstFaceEdgeRange(*this, _fh); - } + ConstFaceEdgeRange fe_range(FaceHandle _fh) const; /** * @return The faces adjacent to the specified face * as a range object suitable for C++11 range based for loops. */ - ConstFaceFaceRange ff_range(FaceHandle _fh) const { - return ConstFaceFaceRange(*this, _fh); - } + ConstFaceFaceRange ff_range(FaceHandle _fh) const; //@} @@ -1400,12 +1357,6 @@ public: bool is_manifold(VertexHandle _vh) const; /** @} */ - - // --- shortcuts --- - - /// returns the face handle of the opposite halfedge - inline FaceHandle opposite_face_handle(HalfedgeHandle _heh) const - { return face_handle(opposite_halfedge_handle(_heh)); } // --- misc --- @@ -1415,7 +1366,7 @@ public: void adjust_outgoing_halfedge(VertexHandle _vh); /// Find halfedge from _vh0 to _vh1. Returns invalid handle if not found. - HalfedgeHandle find_halfedge(VertexHandle _start_vh, VertexHandle _end_vh) const; + SmartHalfedgeHandle find_halfedge(VertexHandle _start_vh, VertexHandle _end_vh) const; /// Vertex valence uint valence(VertexHandle _vh) const; /// Face valence @@ -1586,6 +1537,39 @@ private: // Working storage for add_face() }; +template <> +struct PolyConnectivity::ElementRange +{ + using Range = ConstVertexRange; + using RangeSkipping = ConstVertexRangeSkipping; +}; + +template <> +struct PolyConnectivity::ElementRange +{ + using Range = ConstHalfedgeRange; + using RangeSkipping = ConstHalfedgeRangeSkipping; +}; + +template <> +struct PolyConnectivity::ElementRange +{ + using Range = ConstEdgeRange; + using RangeSkipping = ConstEdgeRangeSkipping; +}; + +template <> +struct PolyConnectivity::ElementRange +{ + using Range = ConstFaceRange; + using RangeSkipping = ConstFaceRangeSkipping; +}; + }//namespace OpenMesh +#define OPENMESH_POLYCONNECTIVITY_INTERFACE_INCLUDE +#include +#include +#undef OPENMESH_POLYCONNECTIVITY_INTERFACE_INCLUDE + #endif//OPENMESH_POLYCONNECTIVITY_HH diff --git a/src/OpenMesh/Core/Mesh/PolyConnectivity_inline_impl.hh b/src/OpenMesh/Core/Mesh/PolyConnectivity_inline_impl.hh new file mode 100644 index 00000000..1e45ee74 --- /dev/null +++ b/src/OpenMesh/Core/Mesh/PolyConnectivity_inline_impl.hh @@ -0,0 +1,832 @@ +/* ========================================================================= * + * * + * OpenMesh * + * Copyright (c) 2001-2015, RWTH-Aachen University * + * Department of Computer Graphics and Multimedia * + * All rights reserved. * + * www.openmesh.org * + * * + *---------------------------------------------------------------------------* + * This file is part of OpenMesh. * + *---------------------------------------------------------------------------* + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * 1. Redistributions of source code must retain the above copyright notice, * + * this list of conditions and the following disclaimer. * + * * + * 2. Redistributions in binary form must reproduce the above copyright * + * notice, this list of conditions and the following disclaimer in the * + * documentation and/or other materials provided with the distribution. * + * * + * 3. Neither the name of the copyright holder nor the names of its * + * contributors may be used to endorse or promote products derived from * + * this software without specific prior written permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER * + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * + * * + * ========================================================================= */ + +#ifndef OPENMESH_POLYCONNECTIVITY_INTERFACE_INCLUDE +#error Do not include this directly, include instead PolyConnectivity.hh +#endif // OPENMESH_POLYCONNECTIVITY_INTERFACE_INCLUDE + +#include +#include + +namespace OpenMesh { + + +inline SmartVertexHandle PolyConnectivity::add_vertex() { return make_smart(new_vertex(), *this); } + +inline SmartHalfedgeHandle PolyConnectivity::next_halfedge_handle(SmartHalfedgeHandle _heh) const { return make_smart(next_halfedge_handle(HalfedgeHandle(_heh)), *this); } +inline SmartHalfedgeHandle PolyConnectivity::prev_halfedge_handle(SmartHalfedgeHandle _heh) const { return make_smart(prev_halfedge_handle(HalfedgeHandle(_heh)), *this); } +inline SmartHalfedgeHandle PolyConnectivity::opposite_halfedge_handle(SmartHalfedgeHandle _heh) const { return make_smart(opposite_halfedge_handle(HalfedgeHandle(_heh)), *this); } +inline SmartHalfedgeHandle PolyConnectivity::ccw_rotated_halfedge_handle(SmartHalfedgeHandle _heh) const { return make_smart(ccw_rotated_halfedge_handle(HalfedgeHandle(_heh)), *this); } +inline SmartHalfedgeHandle PolyConnectivity::cw_rotated_halfedge_handle(SmartHalfedgeHandle _heh) const { return make_smart(cw_rotated_halfedge_handle(HalfedgeHandle(_heh)), *this); } + +inline SmartHalfedgeHandle PolyConnectivity::s_halfedge_handle(SmartEdgeHandle _eh, unsigned int _i) { return make_smart(ArrayKernel::s_halfedge_handle(EdgeHandle(_eh), _i), _eh.mesh()); } +inline SmartEdgeHandle PolyConnectivity::s_edge_handle(SmartHalfedgeHandle _heh) { return make_smart(ArrayKernel::s_edge_handle(HalfedgeHandle(_heh)), _heh.mesh()); } + +inline SmartHalfedgeHandle PolyConnectivity::halfedge_handle(SmartEdgeHandle _eh, unsigned int _i) const { return make_smart(halfedge_handle(EdgeHandle(_eh), _i), *this); } +inline SmartEdgeHandle PolyConnectivity::edge_handle(SmartHalfedgeHandle _heh) const { return make_smart(edge_handle(HalfedgeHandle(_heh)), *this); } +inline SmartHalfedgeHandle PolyConnectivity::halfedge_handle(SmartFaceHandle _fh) const { return make_smart(halfedge_handle(FaceHandle(_fh)), *this); } +inline SmartHalfedgeHandle PolyConnectivity::halfedge_handle(SmartVertexHandle _vh) const { return make_smart(halfedge_handle(VertexHandle(_vh)), *this); } + +inline SmartFaceHandle PolyConnectivity::face_handle(SmartHalfedgeHandle _heh) const { return make_smart(face_handle(HalfedgeHandle(_heh)), *this); } + +inline SmartFaceHandle PolyConnectivity::opposite_face_handle(HalfedgeHandle _heh) const { return make_smart(face_handle(opposite_halfedge_handle(_heh)), *this); } + + +/// Generic class for vertex/halfedge/edge/face ranges. +template +class EntityRange : public SmartRangeT, typename RangeTraitT::ITER_TYPE::SmartHandle> { + public: + typedef typename RangeTraitT::ITER_TYPE iterator; + typedef typename RangeTraitT::ITER_TYPE const_iterator; + + explicit EntityRange(typename RangeTraitT::CONTAINER_TYPE &container) : container_(container) {} + typename RangeTraitT::ITER_TYPE begin() const { return RangeTraitT::begin(container_); } + typename RangeTraitT::ITER_TYPE end() const { return RangeTraitT::end(container_); } + + private: + typename RangeTraitT::CONTAINER_TYPE &container_; +}; + +/// Generic class for iterator ranges. +template +//class CirculatorRange : public SmartRangeT, decltype (make_smart(std::declval(), std::declval()))>{ +class CirculatorRange : public SmartRangeT, typename SmartHandle::type>{ + public: + typedef typename CirculatorRangeTraitT::ITER_TYPE ITER_TYPE; + typedef typename CirculatorRangeTraitT::CENTER_ENTITY_TYPE CENTER_ENTITY_TYPE; + typedef typename CirculatorRangeTraitT::CONTAINER_TYPE CONTAINER_TYPE; + typedef ITER_TYPE iterator; + typedef ITER_TYPE const_iterator; + + CirculatorRange( + const CONTAINER_TYPE &container, + CENTER_ENTITY_TYPE center) : + container_(container), center_(center) {} + ITER_TYPE begin() const { return CirculatorRangeTraitT::begin(container_, center_); } + ITER_TYPE end() const { return CirculatorRangeTraitT::end(container_, center_); } + + private: + const CONTAINER_TYPE &container_; + CENTER_ENTITY_TYPE center_; +}; + + +inline PolyConnectivity::ConstVertexRangeSkipping PolyConnectivity::vertices() const { return ConstVertexRangeSkipping(*this); } +inline PolyConnectivity::ConstVertexRange PolyConnectivity::all_vertices() const { return ConstVertexRange(*this); } +inline PolyConnectivity::ConstHalfedgeRangeSkipping PolyConnectivity::halfedges() const { return ConstHalfedgeRangeSkipping(*this); } +inline PolyConnectivity::ConstHalfedgeRange PolyConnectivity::all_halfedges() const { return ConstHalfedgeRange(*this); } +inline PolyConnectivity::ConstEdgeRangeSkipping PolyConnectivity::edges() const { return ConstEdgeRangeSkipping(*this); } +inline PolyConnectivity::ConstEdgeRange PolyConnectivity::all_edges() const { return ConstEdgeRange(*this); } +inline PolyConnectivity::ConstFaceRangeSkipping PolyConnectivity::faces() const { return ConstFaceRangeSkipping(*this); } +inline PolyConnectivity::ConstFaceRange PolyConnectivity::all_faces() const { return ConstFaceRange(*this); } + +template <> inline PolyConnectivity::ConstVertexRangeSkipping PolyConnectivity::elements() const { return vertices(); } +template <> inline PolyConnectivity::ConstVertexRange PolyConnectivity::all_elements() const { return all_vertices(); } +template <> inline PolyConnectivity::ConstHalfedgeRangeSkipping PolyConnectivity::elements() const { return halfedges(); } +template <> inline PolyConnectivity::ConstHalfedgeRange PolyConnectivity::all_elements() const { return all_halfedges(); } +template <> inline PolyConnectivity::ConstEdgeRangeSkipping PolyConnectivity::elements() const { return edges(); } +template <> inline PolyConnectivity::ConstEdgeRange PolyConnectivity::all_elements() const { return all_edges(); } +template <> inline PolyConnectivity::ConstFaceRangeSkipping PolyConnectivity::elements() const { return faces(); } +template <> inline PolyConnectivity::ConstFaceRange PolyConnectivity::all_elements() const { return all_faces(); } + + +inline PolyConnectivity::ConstVertexVertexRange PolyConnectivity::vv_range(VertexHandle _vh) const { + return ConstVertexVertexRange(*this, _vh); +} + +inline PolyConnectivity::ConstVertexIHalfedgeRange PolyConnectivity::vih_range(VertexHandle _vh) const { + return ConstVertexIHalfedgeRange(*this, _vh); +} + +inline PolyConnectivity::ConstVertexOHalfedgeRange PolyConnectivity::voh_range(VertexHandle _vh) const { + return ConstVertexOHalfedgeRange(*this, _vh); +} + +inline PolyConnectivity::ConstVertexEdgeRange PolyConnectivity::ve_range(VertexHandle _vh) const { + return ConstVertexEdgeRange(*this, _vh); +} + +inline PolyConnectivity::ConstVertexFaceRange PolyConnectivity::vf_range(VertexHandle _vh) const { + return ConstVertexFaceRange(*this, _vh); +} + +inline PolyConnectivity::ConstFaceVertexRange PolyConnectivity::fv_range(FaceHandle _fh) const { + return ConstFaceVertexRange(*this, _fh); +} + +inline PolyConnectivity::ConstFaceHalfedgeRange PolyConnectivity::fh_range(FaceHandle _fh) const { + return ConstFaceHalfedgeRange(*this, _fh); +} + +inline PolyConnectivity::ConstFaceEdgeRange PolyConnectivity::fe_range(FaceHandle _fh) const { + return ConstFaceEdgeRange(*this, _fh); +} + +inline PolyConnectivity::ConstFaceFaceRange PolyConnectivity::ff_range(FaceHandle _fh) const { + return ConstFaceFaceRange(*this, _fh); +} + + + +inline PolyConnectivity::VertexIter PolyConnectivity::vertices_begin() +{ return VertexIter(*this, VertexHandle(0)); } + +inline PolyConnectivity::ConstVertexIter PolyConnectivity::vertices_begin() const +{ return ConstVertexIter(*this, VertexHandle(0)); } + +inline PolyConnectivity::VertexIter PolyConnectivity::vertices_end() +{ return VertexIter(*this, VertexHandle( int(n_vertices() ) )); } + +inline PolyConnectivity::ConstVertexIter PolyConnectivity::vertices_end() const +{ return ConstVertexIter(*this, VertexHandle( int(n_vertices()) )); } + +inline PolyConnectivity::HalfedgeIter PolyConnectivity::halfedges_begin() +{ return HalfedgeIter(*this, HalfedgeHandle(0)); } + +inline PolyConnectivity::ConstHalfedgeIter PolyConnectivity::halfedges_begin() const +{ return ConstHalfedgeIter(*this, HalfedgeHandle(0)); } + +inline PolyConnectivity::HalfedgeIter PolyConnectivity::halfedges_end() +{ return HalfedgeIter(*this, HalfedgeHandle(int(n_halfedges()))); } + +inline PolyConnectivity::ConstHalfedgeIter PolyConnectivity::halfedges_end() const +{ return ConstHalfedgeIter(*this, HalfedgeHandle(int(n_halfedges()))); } + +inline PolyConnectivity::EdgeIter PolyConnectivity::edges_begin() +{ return EdgeIter(*this, EdgeHandle(0)); } + +inline PolyConnectivity::ConstEdgeIter PolyConnectivity::edges_begin() const +{ return ConstEdgeIter(*this, EdgeHandle(0)); } + +inline PolyConnectivity::EdgeIter PolyConnectivity::edges_end() +{ return EdgeIter(*this, EdgeHandle(int(n_edges()))); } + +inline PolyConnectivity::ConstEdgeIter PolyConnectivity::edges_end() const +{ return ConstEdgeIter(*this, EdgeHandle(int(n_edges()))); } + +inline PolyConnectivity::FaceIter PolyConnectivity::faces_begin() +{ return FaceIter(*this, FaceHandle(0)); } + +inline PolyConnectivity::ConstFaceIter PolyConnectivity::faces_begin() const +{ return ConstFaceIter(*this, FaceHandle(0)); } + +inline PolyConnectivity::FaceIter PolyConnectivity::faces_end() +{ return FaceIter(*this, FaceHandle(int(n_faces()))); } + + +inline PolyConnectivity::ConstFaceIter PolyConnectivity::faces_end() const +{ return ConstFaceIter(*this, FaceHandle(int(n_faces()))); } + +inline PolyConnectivity::VertexIter PolyConnectivity::vertices_sbegin() +{ return VertexIter(*this, VertexHandle(0), true); } + +inline PolyConnectivity::ConstVertexIter PolyConnectivity::vertices_sbegin() const +{ return ConstVertexIter(*this, VertexHandle(0), true); } + +inline PolyConnectivity::HalfedgeIter PolyConnectivity::halfedges_sbegin() +{ return HalfedgeIter(*this, HalfedgeHandle(0), true); } + +inline PolyConnectivity::ConstHalfedgeIter PolyConnectivity::halfedges_sbegin() const +{ return ConstHalfedgeIter(*this, HalfedgeHandle(0), true); } + +inline PolyConnectivity::EdgeIter PolyConnectivity::edges_sbegin() +{ return EdgeIter(*this, EdgeHandle(0), true); } + +inline PolyConnectivity::ConstEdgeIter PolyConnectivity::edges_sbegin() const +{ return ConstEdgeIter(*this, EdgeHandle(0), true); } + +inline PolyConnectivity::FaceIter PolyConnectivity::faces_sbegin() +{ return FaceIter(*this, FaceHandle(0), true); } + +inline PolyConnectivity::ConstFaceIter PolyConnectivity::faces_sbegin() const +{ return ConstFaceIter(*this, FaceHandle(0), true); } + +inline PolyConnectivity::VertexVertexIter PolyConnectivity::vv_iter(ArrayKernel::VertexHandle _vh) +{ return VertexVertexIter(*this, _vh); } + +inline PolyConnectivity::VertexVertexCWIter PolyConnectivity::vv_cwiter(ArrayKernel::VertexHandle _vh) +{ return VertexVertexCWIter(*this, _vh); } + +inline PolyConnectivity::VertexVertexCCWIter PolyConnectivity::vv_ccwiter(ArrayKernel::VertexHandle _vh) +{ return VertexVertexCCWIter(*this, _vh); } + +inline PolyConnectivity::VertexIHalfedgeIter PolyConnectivity::vih_iter(ArrayKernel::VertexHandle _vh) +{ return VertexIHalfedgeIter(*this, _vh); } + +inline PolyConnectivity::VertexIHalfedgeCWIter PolyConnectivity::vih_cwiter(ArrayKernel::VertexHandle _vh) +{ return VertexIHalfedgeCWIter(*this, _vh); } + +inline PolyConnectivity::VertexIHalfedgeCCWIter PolyConnectivity::vih_ccwiter(ArrayKernel::VertexHandle _vh) +{ return VertexIHalfedgeCCWIter(*this, _vh); } + +inline PolyConnectivity::VertexOHalfedgeIter PolyConnectivity::voh_iter(ArrayKernel::VertexHandle _vh) +{ return VertexOHalfedgeIter(*this, _vh); } + +inline PolyConnectivity::VertexOHalfedgeCWIter PolyConnectivity::voh_cwiter(ArrayKernel::VertexHandle _vh) +{ return VertexOHalfedgeCWIter(*this, _vh); } + +inline PolyConnectivity::VertexOHalfedgeCCWIter PolyConnectivity::voh_ccwiter(ArrayKernel::VertexHandle _vh) +{ return VertexOHalfedgeCCWIter(*this, _vh); } + +inline PolyConnectivity::VertexEdgeIter PolyConnectivity::ve_iter(ArrayKernel::VertexHandle _vh) +{ return VertexEdgeIter(*this, _vh); } + +inline PolyConnectivity::VertexEdgeCWIter PolyConnectivity::ve_cwiter(ArrayKernel::VertexHandle _vh) +{ return VertexEdgeCWIter(*this, _vh); } + +inline PolyConnectivity::VertexEdgeCCWIter PolyConnectivity::ve_ccwiter(ArrayKernel::VertexHandle _vh) +{ return VertexEdgeCCWIter(*this, _vh); } + +inline PolyConnectivity::VertexFaceIter PolyConnectivity::vf_iter(ArrayKernel::VertexHandle _vh) +{ return VertexFaceIter(*this, _vh); } + +inline PolyConnectivity::VertexFaceCWIter PolyConnectivity::vf_cwiter(ArrayKernel::VertexHandle _vh) +{ return VertexFaceCWIter(*this, _vh); } + +inline PolyConnectivity::VertexFaceCCWIter PolyConnectivity::vf_ccwiter(ArrayKernel::VertexHandle _vh) +{ return VertexFaceCCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexVertexIter PolyConnectivity::cvv_iter(ArrayKernel::VertexHandle _vh) const +{ return ConstVertexVertexIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexVertexCWIter PolyConnectivity::cvv_cwiter(ArrayKernel::VertexHandle _vh) const +{ return ConstVertexVertexCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexVertexCCWIter PolyConnectivity::cvv_ccwiter(ArrayKernel::VertexHandle _vh) const +{ return ConstVertexVertexCCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexIHalfedgeIter PolyConnectivity::cvih_iter(ArrayKernel::VertexHandle _vh) const +{ return ConstVertexIHalfedgeIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexIHalfedgeCWIter PolyConnectivity::cvih_cwiter(ArrayKernel::VertexHandle _vh) const +{ return ConstVertexIHalfedgeCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexIHalfedgeCCWIter PolyConnectivity::cvih_ccwiter(ArrayKernel::VertexHandle _vh) const +{ return ConstVertexIHalfedgeCCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexOHalfedgeIter PolyConnectivity::cvoh_iter(ArrayKernel::VertexHandle _vh) const +{ return ConstVertexOHalfedgeIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexOHalfedgeCWIter PolyConnectivity::cvoh_cwiter(ArrayKernel::VertexHandle _vh) const +{ return ConstVertexOHalfedgeCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexOHalfedgeCCWIter PolyConnectivity::cvoh_ccwiter(ArrayKernel::VertexHandle _vh) const +{ return ConstVertexOHalfedgeCCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexEdgeIter PolyConnectivity::cve_iter(ArrayKernel::VertexHandle _vh) const +{ return ConstVertexEdgeIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexEdgeCWIter PolyConnectivity::cve_cwiter(ArrayKernel::VertexHandle _vh) const +{ return ConstVertexEdgeCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexEdgeCCWIter PolyConnectivity::cve_ccwiter(ArrayKernel::VertexHandle _vh) const +{ return ConstVertexEdgeCCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexFaceIter PolyConnectivity::cvf_iter(ArrayKernel::VertexHandle _vh) const +{ return ConstVertexFaceIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexFaceCWIter PolyConnectivity::cvf_cwiter(ArrayKernel::VertexHandle _vh) const +{ return ConstVertexFaceCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexFaceCCWIter PolyConnectivity::cvf_ccwiter(ArrayKernel::VertexHandle _vh) const +{ return ConstVertexFaceCCWIter(*this, _vh); } + +inline PolyConnectivity::FaceVertexIter PolyConnectivity::fv_iter(ArrayKernel::FaceHandle _fh) +{ return FaceVertexIter(*this, _fh); } + +inline PolyConnectivity::FaceVertexCWIter PolyConnectivity::fv_cwiter(ArrayKernel::FaceHandle _fh) +{ return FaceVertexCWIter(*this, _fh); } + +inline PolyConnectivity::FaceVertexCCWIter PolyConnectivity::fv_ccwiter(ArrayKernel::FaceHandle _fh) +{ return FaceVertexCCWIter(*this, _fh); } + +inline PolyConnectivity::FaceHalfedgeIter PolyConnectivity::fh_iter(ArrayKernel::FaceHandle _fh) +{ return FaceHalfedgeIter(*this, _fh); } + +inline PolyConnectivity::FaceHalfedgeCWIter PolyConnectivity::fh_cwiter(ArrayKernel::FaceHandle _fh) +{ return FaceHalfedgeCWIter(*this, _fh); } + +inline PolyConnectivity::FaceHalfedgeCCWIter PolyConnectivity::fh_ccwiter(ArrayKernel::FaceHandle _fh) +{ return FaceHalfedgeCCWIter(*this, _fh); } + +inline PolyConnectivity::FaceEdgeIter PolyConnectivity::fe_iter(ArrayKernel::FaceHandle _fh) +{ return FaceEdgeIter(*this, _fh); } + +inline PolyConnectivity::FaceEdgeCWIter PolyConnectivity::fe_cwiter(ArrayKernel::FaceHandle _fh) +{ return FaceEdgeCWIter(*this, _fh); } + +inline PolyConnectivity::FaceEdgeCCWIter PolyConnectivity::fe_ccwiter(ArrayKernel::FaceHandle _fh) +{ return FaceEdgeCCWIter(*this, _fh); } + +inline PolyConnectivity::FaceFaceIter PolyConnectivity::ff_iter(ArrayKernel::FaceHandle _fh) +{ return FaceFaceIter(*this, _fh); } + +inline PolyConnectivity::FaceFaceCWIter PolyConnectivity::ff_cwiter(ArrayKernel::FaceHandle _fh) +{ return FaceFaceCWIter(*this, _fh); } + +inline PolyConnectivity::FaceFaceCCWIter PolyConnectivity::ff_ccwiter(ArrayKernel::FaceHandle _fh) +{ return FaceFaceCCWIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceVertexIter PolyConnectivity::cfv_iter(ArrayKernel::FaceHandle _fh) const +{ return ConstFaceVertexIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceVertexCWIter PolyConnectivity::cfv_cwiter(ArrayKernel::FaceHandle _fh) const +{ return ConstFaceVertexCWIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceVertexCCWIter PolyConnectivity::cfv_ccwiter(ArrayKernel::FaceHandle _fh) const +{ return ConstFaceVertexCCWIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceHalfedgeIter PolyConnectivity::cfh_iter(ArrayKernel::FaceHandle _fh) const +{ return ConstFaceHalfedgeIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceHalfedgeCWIter PolyConnectivity::cfh_cwiter(ArrayKernel::FaceHandle _fh) const +{ return ConstFaceHalfedgeCWIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceHalfedgeCCWIter PolyConnectivity::cfh_ccwiter(ArrayKernel::FaceHandle _fh) const +{ return ConstFaceHalfedgeCCWIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceEdgeIter PolyConnectivity::cfe_iter(ArrayKernel::FaceHandle _fh) const +{ return ConstFaceEdgeIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceEdgeCWIter PolyConnectivity::cfe_cwiter(ArrayKernel::FaceHandle _fh) const +{ return ConstFaceEdgeCWIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceEdgeCCWIter PolyConnectivity::cfe_ccwiter(ArrayKernel::FaceHandle _fh) const +{ return ConstFaceEdgeCCWIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceFaceIter PolyConnectivity::cff_iter(ArrayKernel::FaceHandle _fh) const +{ return ConstFaceFaceIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceFaceCWIter PolyConnectivity::cff_cwiter(ArrayKernel::FaceHandle _fh) const +{ return ConstFaceFaceCWIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceFaceCCWIter PolyConnectivity::cff_ccwiter(ArrayKernel::FaceHandle _fh) const +{ return ConstFaceFaceCCWIter(*this, _fh); } + + +inline PolyConnectivity::VertexVertexIter PolyConnectivity::vv_begin(VertexHandle _vh) +{ return VertexVertexIter(*this, _vh); } + +inline PolyConnectivity::VertexVertexCWIter PolyConnectivity::vv_cwbegin(VertexHandle _vh) +{ return VertexVertexCWIter(*this, _vh); } + +inline PolyConnectivity::VertexVertexCCWIter PolyConnectivity::vv_ccwbegin(VertexHandle _vh) +{ return VertexVertexCCWIter(*this, _vh); } + +inline PolyConnectivity::VertexIHalfedgeIter PolyConnectivity::vih_begin(VertexHandle _vh) +{ return VertexIHalfedgeIter(*this, _vh); } + +inline PolyConnectivity::VertexIHalfedgeCWIter PolyConnectivity::vih_cwbegin(VertexHandle _vh) +{ return VertexIHalfedgeCWIter(*this, _vh); } + +inline PolyConnectivity::VertexIHalfedgeCCWIter PolyConnectivity::vih_ccwbegin(VertexHandle _vh) +{ return VertexIHalfedgeCCWIter(*this, _vh); } + +inline PolyConnectivity::VertexOHalfedgeIter PolyConnectivity::voh_begin(VertexHandle _vh) +{ return VertexOHalfedgeIter(*this, _vh); } + +inline PolyConnectivity::VertexOHalfedgeCWIter PolyConnectivity::voh_cwbegin(VertexHandle _vh) +{ return VertexOHalfedgeCWIter(*this, _vh); } + +inline PolyConnectivity::VertexOHalfedgeCCWIter PolyConnectivity::voh_ccwbegin(VertexHandle _vh) +{ return VertexOHalfedgeCCWIter(*this, _vh); } + +inline PolyConnectivity::VertexEdgeIter PolyConnectivity::ve_begin(VertexHandle _vh) +{ return VertexEdgeIter(*this, _vh); } + +inline PolyConnectivity::VertexEdgeCWIter PolyConnectivity::ve_cwbegin(VertexHandle _vh) +{ return VertexEdgeCWIter(*this, _vh); } + +inline PolyConnectivity::VertexEdgeCCWIter PolyConnectivity::ve_ccwbegin(VertexHandle _vh) +{ return VertexEdgeCCWIter(*this, _vh); } + +inline PolyConnectivity::VertexFaceIter PolyConnectivity::vf_begin(VertexHandle _vh) +{ return VertexFaceIter(*this, _vh); } + +inline PolyConnectivity::VertexFaceCWIter PolyConnectivity::vf_cwbegin(VertexHandle _vh) +{ return VertexFaceCWIter(*this, _vh); } + +inline PolyConnectivity::VertexFaceCCWIter PolyConnectivity::vf_ccwbegin(VertexHandle _vh) +{ return VertexFaceCCWIter(*this, _vh); } + + +inline PolyConnectivity::ConstVertexVertexIter PolyConnectivity::cvv_begin(VertexHandle _vh) const +{ return ConstVertexVertexIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexVertexCWIter PolyConnectivity::cvv_cwbegin(VertexHandle _vh) const +{ return ConstVertexVertexCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexVertexCCWIter PolyConnectivity::cvv_ccwbegin(VertexHandle _vh) const +{ return ConstVertexVertexCCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexIHalfedgeIter PolyConnectivity::cvih_begin(VertexHandle _vh) const +{ return ConstVertexIHalfedgeIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexIHalfedgeCWIter PolyConnectivity::cvih_cwbegin(VertexHandle _vh) const +{ return ConstVertexIHalfedgeCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexIHalfedgeCCWIter PolyConnectivity::cvih_ccwbegin(VertexHandle _vh) const +{ return ConstVertexIHalfedgeCCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexOHalfedgeIter PolyConnectivity::cvoh_begin(VertexHandle _vh) const +{ return ConstVertexOHalfedgeIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexOHalfedgeCWIter PolyConnectivity::cvoh_cwbegin(VertexHandle _vh) const +{ return ConstVertexOHalfedgeCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexOHalfedgeCCWIter PolyConnectivity::cvoh_ccwbegin(VertexHandle _vh) const +{ return ConstVertexOHalfedgeCCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexEdgeIter PolyConnectivity::cve_begin(VertexHandle _vh) const +{ return ConstVertexEdgeIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexEdgeCWIter PolyConnectivity::cve_cwbegin(VertexHandle _vh) const +{ return ConstVertexEdgeCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexEdgeCCWIter PolyConnectivity::cve_ccwbegin(VertexHandle _vh) const +{ return ConstVertexEdgeCCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexFaceIter PolyConnectivity::cvf_begin(VertexHandle _vh) const +{ return ConstVertexFaceIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexFaceCWIter PolyConnectivity::cvf_cwbegin(VertexHandle _vh) const +{ return ConstVertexFaceCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexFaceCCWIter PolyConnectivity::cvf_ccwbegin(VertexHandle _vh) const +{ return ConstVertexFaceCCWIter(*this, _vh); } + + +inline PolyConnectivity::FaceVertexIter PolyConnectivity::fv_begin(FaceHandle _fh) +{ return FaceVertexIter(*this, _fh); } + +inline PolyConnectivity::FaceVertexCWIter PolyConnectivity::fv_cwbegin(FaceHandle _fh) +{ return FaceVertexCWIter(*this, _fh); } + +inline PolyConnectivity::FaceVertexCCWIter PolyConnectivity::fv_ccwbegin(FaceHandle _fh) +{ return FaceVertexCCWIter(*this, _fh); } + +inline PolyConnectivity::FaceHalfedgeIter PolyConnectivity::fh_begin(FaceHandle _fh) +{ return FaceHalfedgeIter(*this, _fh); } + +inline PolyConnectivity::FaceHalfedgeCWIter PolyConnectivity::fh_cwbegin(FaceHandle _fh) +{ return FaceHalfedgeCWIter(*this, _fh); } + +inline PolyConnectivity::FaceHalfedgeCCWIter PolyConnectivity::fh_ccwbegin(FaceHandle _fh) +{ return FaceHalfedgeCCWIter(*this, _fh); } + +inline PolyConnectivity::FaceEdgeIter PolyConnectivity::fe_begin(FaceHandle _fh) +{ return FaceEdgeIter(*this, _fh); } + +inline PolyConnectivity::FaceEdgeCWIter PolyConnectivity::fe_cwbegin(FaceHandle _fh) +{ return FaceEdgeCWIter(*this, _fh); } + +inline PolyConnectivity::FaceEdgeCCWIter PolyConnectivity::fe_ccwbegin(FaceHandle _fh) +{ return FaceEdgeCCWIter(*this, _fh); } + +inline PolyConnectivity::FaceFaceIter PolyConnectivity::ff_begin(FaceHandle _fh) +{ return FaceFaceIter(*this, _fh); } + +inline PolyConnectivity::FaceFaceCWIter PolyConnectivity::ff_cwbegin(FaceHandle _fh) +{ return FaceFaceCWIter(*this, _fh); } + +inline PolyConnectivity::FaceFaceCCWIter PolyConnectivity::ff_ccwbegin(FaceHandle _fh) +{ return FaceFaceCCWIter(*this, _fh); } + +inline PolyConnectivity::HalfedgeLoopIter PolyConnectivity::hl_begin(HalfedgeHandle _heh) +{ return HalfedgeLoopIter(*this, _heh); } + +inline PolyConnectivity::HalfedgeLoopCWIter PolyConnectivity::hl_cwbegin(HalfedgeHandle _heh) +{ return HalfedgeLoopCWIter(*this, _heh); } + +inline PolyConnectivity::HalfedgeLoopCCWIter PolyConnectivity::hl_ccwbegin(HalfedgeHandle _heh) +{ return HalfedgeLoopCCWIter(*this, _heh); } + + +inline PolyConnectivity::ConstFaceVertexIter PolyConnectivity::cfv_begin(FaceHandle _fh) const +{ return ConstFaceVertexIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceVertexCWIter PolyConnectivity::cfv_cwbegin(FaceHandle _fh) const +{ return ConstFaceVertexCWIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceVertexCCWIter PolyConnectivity::cfv_ccwbegin(FaceHandle _fh) const +{ return ConstFaceVertexCCWIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceHalfedgeIter PolyConnectivity::cfh_begin(FaceHandle _fh) const +{ return ConstFaceHalfedgeIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceHalfedgeCWIter PolyConnectivity::cfh_cwbegin(FaceHandle _fh) const +{ return ConstFaceHalfedgeCWIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceHalfedgeCCWIter PolyConnectivity::cfh_ccwbegin(FaceHandle _fh) const +{ return ConstFaceHalfedgeCCWIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceEdgeIter PolyConnectivity::cfe_begin(FaceHandle _fh) const +{ return ConstFaceEdgeIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceEdgeCWIter PolyConnectivity::cfe_cwbegin(FaceHandle _fh) const +{ return ConstFaceEdgeCWIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceEdgeCCWIter PolyConnectivity::cfe_ccwbegin(FaceHandle _fh) const +{ return ConstFaceEdgeCCWIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceFaceIter PolyConnectivity::cff_begin(FaceHandle _fh) const +{ return ConstFaceFaceIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceFaceCWIter PolyConnectivity::cff_cwbegin(FaceHandle _fh) const +{ return ConstFaceFaceCWIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceFaceCCWIter PolyConnectivity::cff_ccwbegin(FaceHandle _fh) const +{ return ConstFaceFaceCCWIter(*this, _fh); } + +inline PolyConnectivity::ConstHalfedgeLoopIter PolyConnectivity::chl_begin(HalfedgeHandle _heh) const +{ return ConstHalfedgeLoopIter(*this, _heh); } + +inline PolyConnectivity::ConstHalfedgeLoopCWIter PolyConnectivity::chl_cwbegin(HalfedgeHandle _heh) const +{ return ConstHalfedgeLoopCWIter(*this, _heh); } + +inline PolyConnectivity::ConstHalfedgeLoopCCWIter PolyConnectivity::chl_ccwbegin(HalfedgeHandle _heh) const +{ return ConstHalfedgeLoopCCWIter(*this, _heh); } + +// 'end' circulators + +inline PolyConnectivity::VertexVertexIter PolyConnectivity::vv_end(VertexHandle _vh) +{ return VertexVertexIter(*this, _vh, true); } + +inline PolyConnectivity::VertexVertexCWIter PolyConnectivity::vv_cwend(VertexHandle _vh) +{ return VertexVertexCWIter(*this, _vh, true); } + +inline PolyConnectivity::VertexVertexCCWIter PolyConnectivity::vv_ccwend(VertexHandle _vh) +{ return VertexVertexCCWIter(*this, _vh, true); } + +inline PolyConnectivity::VertexIHalfedgeIter PolyConnectivity::vih_end(VertexHandle _vh) +{ return VertexIHalfedgeIter(*this, _vh, true); } + +inline PolyConnectivity::VertexIHalfedgeCWIter PolyConnectivity::vih_cwend(VertexHandle _vh) +{ return VertexIHalfedgeCWIter(*this, _vh, true); } + +inline PolyConnectivity::VertexIHalfedgeCCWIter PolyConnectivity::vih_ccwend(VertexHandle _vh) +{ return VertexIHalfedgeCCWIter(*this, _vh, true); } + +inline PolyConnectivity::VertexOHalfedgeIter PolyConnectivity::voh_end(VertexHandle _vh) +{ return VertexOHalfedgeIter(*this, _vh, true); } + +inline PolyConnectivity::VertexOHalfedgeCWIter PolyConnectivity::voh_cwend(VertexHandle _vh) +{ return VertexOHalfedgeCWIter(*this, _vh, true); } + +inline PolyConnectivity::VertexOHalfedgeCCWIter PolyConnectivity::voh_ccwend(VertexHandle _vh) +{ return VertexOHalfedgeCCWIter(*this, _vh, true); } + +inline PolyConnectivity::VertexEdgeIter PolyConnectivity::ve_end(VertexHandle _vh) +{ return VertexEdgeIter(*this, _vh, true); } + +inline PolyConnectivity::VertexEdgeCWIter PolyConnectivity::ve_cwend(VertexHandle _vh) +{ return VertexEdgeCWIter(*this, _vh, true); } + +inline PolyConnectivity::VertexEdgeCCWIter PolyConnectivity::ve_ccwend(VertexHandle _vh) +{ return VertexEdgeCCWIter(*this, _vh, true); } + +inline PolyConnectivity::VertexFaceIter PolyConnectivity::vf_end(VertexHandle _vh) +{ return VertexFaceIter(*this, _vh, true); } + +inline PolyConnectivity::VertexFaceCWIter PolyConnectivity::vf_cwend(VertexHandle _vh) +{ return VertexFaceCWIter(*this, _vh, true); } + +inline PolyConnectivity::VertexFaceCCWIter PolyConnectivity::vf_ccwend(VertexHandle _vh) +{ return VertexFaceCCWIter(*this, _vh, true); } + + +inline PolyConnectivity::ConstVertexVertexIter PolyConnectivity::cvv_end(VertexHandle _vh) const +{ return ConstVertexVertexIter(*this, _vh, true); } + +inline PolyConnectivity::ConstVertexVertexCWIter PolyConnectivity::cvv_cwend(VertexHandle _vh) const +{ return ConstVertexVertexCWIter(*this, _vh, true); } + +inline PolyConnectivity::ConstVertexVertexCCWIter PolyConnectivity::cvv_ccwend(VertexHandle _vh) const +{ return ConstVertexVertexCCWIter(*this, _vh, true); } + +inline PolyConnectivity::ConstVertexIHalfedgeIter PolyConnectivity::cvih_end(VertexHandle _vh) const +{ return ConstVertexIHalfedgeIter(*this, _vh, true); } + +inline PolyConnectivity::ConstVertexIHalfedgeCWIter PolyConnectivity::cvih_cwend(VertexHandle _vh) const +{ return ConstVertexIHalfedgeCWIter(*this, _vh, true); } + +inline PolyConnectivity::ConstVertexIHalfedgeCCWIter PolyConnectivity::cvih_ccwend(VertexHandle _vh) const +{ return ConstVertexIHalfedgeCCWIter(*this, _vh, true); } + +inline PolyConnectivity::ConstVertexOHalfedgeIter PolyConnectivity::cvoh_end(VertexHandle _vh) const +{ return ConstVertexOHalfedgeIter(*this, _vh, true); } + +inline PolyConnectivity::ConstVertexOHalfedgeCWIter PolyConnectivity::cvoh_cwend(VertexHandle _vh) const +{ return ConstVertexOHalfedgeCWIter(*this, _vh, true); } + +inline PolyConnectivity::ConstVertexOHalfedgeCCWIter PolyConnectivity::cvoh_ccwend(VertexHandle _vh) const +{ return ConstVertexOHalfedgeCCWIter(*this, _vh, true); } + +inline PolyConnectivity::ConstVertexEdgeIter PolyConnectivity::cve_end(VertexHandle _vh) const +{ return ConstVertexEdgeIter(*this, _vh, true); } + +inline PolyConnectivity::ConstVertexEdgeCWIter PolyConnectivity::cve_cwend(VertexHandle _vh) const +{ return ConstVertexEdgeCWIter(*this, _vh, true); } + +inline PolyConnectivity::ConstVertexEdgeCCWIter PolyConnectivity::cve_ccwend(VertexHandle _vh) const +{ return ConstVertexEdgeCCWIter(*this, _vh, true); } + +inline PolyConnectivity::ConstVertexFaceIter PolyConnectivity::cvf_end(VertexHandle _vh) const +{ return ConstVertexFaceIter(*this, _vh, true); } + +inline PolyConnectivity::ConstVertexFaceCWIter PolyConnectivity::cvf_cwend(VertexHandle _vh) const +{ return ConstVertexFaceCWIter(*this, _vh, true); } + +inline PolyConnectivity::ConstVertexFaceCCWIter PolyConnectivity::cvf_ccwend(VertexHandle _vh) const +{ return ConstVertexFaceCCWIter(*this, _vh, true); } + + +inline PolyConnectivity::FaceVertexIter PolyConnectivity::fv_end(FaceHandle _fh) +{ return FaceVertexIter(*this, _fh, true); } + +inline PolyConnectivity::FaceVertexCWIter PolyConnectivity::fv_cwend(FaceHandle _fh) +{ return FaceVertexCWIter(*this, _fh, true); } + +inline PolyConnectivity::FaceVertexCCWIter PolyConnectivity::fv_ccwend(FaceHandle _fh) +{ return FaceVertexCCWIter(*this, _fh, true); } + +inline PolyConnectivity::FaceHalfedgeIter PolyConnectivity::fh_end(FaceHandle _fh) +{ return FaceHalfedgeIter(*this, _fh, true); } + +inline PolyConnectivity::FaceHalfedgeCWIter PolyConnectivity::fh_cwend(FaceHandle _fh) +{ return FaceHalfedgeCWIter(*this, _fh, true); } + +inline PolyConnectivity::FaceHalfedgeCCWIter PolyConnectivity::fh_ccwend(FaceHandle _fh) +{ return FaceHalfedgeCCWIter(*this, _fh, true); } + +inline PolyConnectivity::FaceEdgeIter PolyConnectivity::fe_end(FaceHandle _fh) +{ return FaceEdgeIter(*this, _fh, true); } + +inline PolyConnectivity::FaceEdgeCWIter PolyConnectivity::fe_cwend(FaceHandle _fh) +{ return FaceEdgeCWIter(*this, _fh, true); } + +inline PolyConnectivity::FaceEdgeCCWIter PolyConnectivity::fe_ccwend(FaceHandle _fh) +{ return FaceEdgeCCWIter(*this, _fh, true); } + +inline PolyConnectivity::FaceFaceIter PolyConnectivity::ff_end(FaceHandle _fh) +{ return FaceFaceIter(*this, _fh, true); } + +inline PolyConnectivity::FaceFaceCWIter PolyConnectivity::ff_cwend(FaceHandle _fh) +{ return FaceFaceCWIter(*this, _fh, true); } + +inline PolyConnectivity::FaceFaceCCWIter PolyConnectivity::ff_ccwend(FaceHandle _fh) +{ return FaceFaceCCWIter(*this, _fh, true); } + +inline PolyConnectivity::HalfedgeLoopIter PolyConnectivity::hl_end(HalfedgeHandle _heh) +{ return HalfedgeLoopIter(*this, _heh, true); } + +inline PolyConnectivity::HalfedgeLoopCWIter PolyConnectivity::hl_cwend(HalfedgeHandle _heh) +{ return HalfedgeLoopCWIter(*this, _heh, true); } + +inline PolyConnectivity::HalfedgeLoopCCWIter PolyConnectivity::hl_ccwend(HalfedgeHandle _heh) +{ return HalfedgeLoopCCWIter(*this, _heh, true); } + + +inline PolyConnectivity::ConstFaceVertexIter PolyConnectivity::cfv_end(FaceHandle _fh) const +{ return ConstFaceVertexIter(*this, _fh, true); } + +inline PolyConnectivity::ConstFaceVertexCWIter PolyConnectivity::cfv_cwend(FaceHandle _fh) const +{ return ConstFaceVertexCWIter(*this, _fh, true); } + +inline PolyConnectivity::ConstFaceVertexCCWIter PolyConnectivity::cfv_ccwend(FaceHandle _fh) const +{ return ConstFaceVertexCCWIter(*this, _fh, true); } + +inline PolyConnectivity::ConstFaceHalfedgeIter PolyConnectivity::cfh_end(FaceHandle _fh) const +{ return ConstFaceHalfedgeIter(*this, _fh, true); } + +inline PolyConnectivity::ConstFaceHalfedgeCWIter PolyConnectivity::cfh_cwend(FaceHandle _fh) const +{ return ConstFaceHalfedgeCWIter(*this, _fh, true); } + +inline PolyConnectivity::ConstFaceHalfedgeCCWIter PolyConnectivity::cfh_ccwend(FaceHandle _fh) const +{ return ConstFaceHalfedgeCCWIter(*this, _fh, true); } + +inline PolyConnectivity::ConstFaceEdgeIter PolyConnectivity::cfe_end(FaceHandle _fh) const +{ return ConstFaceEdgeIter(*this, _fh, true); } + +inline PolyConnectivity::ConstFaceEdgeCWIter PolyConnectivity::cfe_cwend(FaceHandle _fh) const +{ return ConstFaceEdgeCWIter(*this, _fh, true); } + +inline PolyConnectivity::ConstFaceEdgeCCWIter PolyConnectivity::cfe_ccwend(FaceHandle _fh) const +{ return ConstFaceEdgeCCWIter(*this, _fh, true); } + +inline PolyConnectivity::ConstFaceFaceIter PolyConnectivity::cff_end(FaceHandle _fh) const +{ return ConstFaceFaceIter(*this, _fh, true); } + +inline PolyConnectivity::ConstFaceFaceCWIter PolyConnectivity::cff_cwend(FaceHandle _fh) const +{ return ConstFaceFaceCWIter(*this, _fh, true); } + +inline PolyConnectivity::ConstFaceFaceCCWIter PolyConnectivity::cff_ccwend(FaceHandle _fh) const +{ return ConstFaceFaceCCWIter(*this, _fh, true); } + +inline PolyConnectivity::ConstHalfedgeLoopIter PolyConnectivity::chl_end(HalfedgeHandle _heh) const +{ return ConstHalfedgeLoopIter(*this, _heh, true); } + +inline PolyConnectivity::ConstHalfedgeLoopCWIter PolyConnectivity::chl_cwend(HalfedgeHandle _heh) const +{ return ConstHalfedgeLoopCWIter(*this, _heh, true); } + +inline PolyConnectivity::ConstHalfedgeLoopCCWIter PolyConnectivity::chl_ccwend(HalfedgeHandle _heh) const +{ return ConstHalfedgeLoopCCWIter(*this, _heh, true); } + + +inline PolyConnectivity::ConstVertexFaceRange SmartVertexHandle::faces() const +{ + assert(mesh() != nullptr); + return mesh()->vf_range(*this); +} + +inline PolyConnectivity::ConstVertexEdgeRange SmartVertexHandle::edges() const +{ + assert(mesh() != nullptr); + return mesh()->ve_range(*this); +} + +inline PolyConnectivity::ConstVertexVertexRange +SmartVertexHandle::vertices() const +{ + assert(mesh() != nullptr); + return mesh()->vv_range(*this); +} + +inline PolyConnectivity::ConstVertexIHalfedgeRange +SmartVertexHandle::incoming_halfedges() const +{ + assert(mesh() != nullptr); + return mesh()->vih_range(*this); +} + +inline PolyConnectivity::ConstVertexOHalfedgeRange +SmartVertexHandle::outgoing_halfedges() const +{ + assert(mesh() != nullptr); + return mesh()->voh_range(*this); +} + +inline PolyConnectivity::ConstFaceVertexRange SmartFaceHandle::vertices() const +{ + assert(mesh() != nullptr); + return mesh()->fv_range(*this); +} + +inline PolyConnectivity::ConstFaceHalfedgeRange +SmartFaceHandle::halfedges() const +{ + assert(mesh() != nullptr); + return mesh()->fh_range(*this); +} + +inline PolyConnectivity::ConstFaceEdgeRange SmartFaceHandle::edges() const +{ + assert(mesh() != nullptr); + return mesh()->fe_range(*this); +} + +inline PolyConnectivity::ConstFaceFaceRange SmartFaceHandle::faces() const +{ + assert(mesh() != nullptr); + return mesh()->ff_range(*this); +} + +}//namespace OpenMesh diff --git a/src/OpenMesh/Core/Mesh/PolyMeshT.hh b/src/OpenMesh/Core/Mesh/PolyMeshT.hh index b29ea40e..a06661f2 100644 --- a/src/OpenMesh/Core/Mesh/PolyMeshT.hh +++ b/src/OpenMesh/Core/Mesh/PolyMeshT.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= @@ -65,6 +60,7 @@ #include #include #include +#include #include @@ -100,11 +96,12 @@ public: //--- item types --- //@{ - /// Determine whether this is a PolyMeshT or TriMeshT ( This function does not check the per face vertex count! It only checks if the datatype is PolyMeshT or TriMeshT ) + /// Determine whether this is a PolyMeshT or TriMeshT (This function does not check the per face vertex count! It only checks if the datatype is PolyMeshT or TriMeshT) + static constexpr bool is_polymesh() { return true; } + static constexpr bool is_trimesh() { return false; } + using ConnectivityTag = PolyConnectivityTag; enum { IsPolyMesh = 1 }; enum { IsTriMesh = 0 }; - static bool is_polymesh() { return true; } - static bool is_trimesh() { return false; } //@} /// \name Mesh Items @@ -201,19 +198,19 @@ public: * * \sa new_vertex(const Point&), new_vertex_dirty() */ - inline VertexHandle new_vertex() - { return Kernel::new_vertex(); } + inline SmartVertexHandle new_vertex() + { return make_smart(Kernel::new_vertex(), this); } /** * \brief Adds a new vertex initialized to a custom position. * * \sa new_vertex(), new_vertex_dirty() */ - inline VertexHandle new_vertex(const Point& _p) + inline SmartVertexHandle new_vertex(const Point& _p) { VertexHandle vh(Kernel::new_vertex()); this->set_point(vh, _p); - return vh; + return make_smart(vh, this); } /** @@ -227,20 +224,20 @@ public: * * \sa new_vertex(const Point &) */ - inline VertexHandle new_vertex_dirty(const Point& _p) + inline SmartVertexHandle new_vertex_dirty(const Point& _p) { VertexHandle vh(Kernel::new_vertex_dirty()); this->set_point(vh, _p); - return vh; + return make_smart(vh, this); } /// Alias for new_vertex(const Point&). - inline VertexHandle add_vertex(const Point& _p) + inline SmartVertexHandle add_vertex(const Point& _p) { return new_vertex(_p); } /// Alias for new_vertex_dirty(). - inline VertexHandle add_vertex_dirty(const Point& _p) - { return new_vertex_dirty(_p); } + inline SmartVertexHandle add_vertex_dirty(const Point& _p) + { return make_smart(new_vertex_dirty(_p), this); } // --- normal vectors --- @@ -274,14 +271,33 @@ public: /** Calculate normal vector for face (_p0, _p1, _p2). */ Normal calc_face_normal(const Point& _p0, const Point& _p1, const Point& _p2) const; + + /// same as calc_face_normal + Normal calc_normal(FaceHandle _fh) const; + /// calculates the average of the vertices defining _fh void calc_face_centroid(FaceHandle _fh, Point& _pt) const { _pt = calc_face_centroid(_fh); } - /// Computes and returns the average of the vertices defining _gh + /// Computes and returns the average of the vertices defining _fh Point calc_face_centroid(FaceHandle _fh) const; + /// Computes and returns the average of the vertices defining _fh (same as calc_face_centroid) + Point calc_centroid(FaceHandle _fh) const; + + /// Computes and returns the average of the vertices defining _eh (same as calc_edge_midpoint) + Point calc_centroid(EdgeHandle _eh) const; + + /// Computes and returns the average of the vertices defining _heh (same as calc_edge_midpoint for edge of halfedge) + Point calc_centroid(HalfedgeHandle _heh) const; + + /// Returns the point of _vh + Point calc_centroid(VertexHandle _vh) const; + + /// Computes and returns the average of the vertices defining the mesh + Point calc_centroid(MeshHandle _mh) const; + /// Update normal for halfedge _heh void update_normal(HalfedgeHandle _heh, const double _feature_angle = 0.8) { this->set_normal(_heh, calc_halfedge_normal(_heh,_feature_angle)); } @@ -311,6 +327,8 @@ public: */ virtual Normal calc_halfedge_normal(HalfedgeHandle _heh, const double _feature_angle = 0.8) const; + /// same as calc_halfedge_normal + Normal calc_normal(HalfedgeHandle, const double _feature_angle = 0.8) const; /** identifies feature edges w.r.t. the minimal dihedral angle for feature edges (in radians) */ /** and the status feature tag */ @@ -356,6 +374,8 @@ public: void calc_vertex_normal_correct(VertexHandle _vh, Normal& _n) const; void calc_vertex_normal_loop(VertexHandle _vh, Normal& _n) const; + /// same as calc_vertex_normal_correct + Normal calc_normal(VertexHandle _vh) const; //@} @@ -406,7 +426,7 @@ public: { Normal edge_vec; calc_edge_vector(_heh, edge_vec); - return edge_vec.sqrnorm(); + return sqrnorm(edge_vec); } /** Calculates the midpoint of the halfedge _heh, defined by the positions of @@ -425,6 +445,15 @@ public: return calc_edge_midpoint(this->halfedge_handle(_eh, 0)); } + /// calculated and returns the average of the two vertex normals + Normal calc_normal(EdgeHandle _eh) const + { + HalfedgeHandle _heh = this->halfedge_handle(_eh, 0); + VertexHandle vh0 = this->from_vertex_handle(_heh); + VertexHandle vh1 = this->to_vertex_handle(_heh); + return 0.5 * (this->calc_normal(vh0) + this->calc_normal(vh1)); + } + /** defines a consistent representation of a sector geometry: the halfedge _in_heh defines the sector orientation the vertex pointed by _in_heh defines the sector center @@ -444,7 +473,7 @@ public: { Normal v0, v1; calc_sector_vectors(_in_heh, v0, v1); - Scalar denom = v0.norm()*v1.norm(); + Scalar denom = norm(v0)*norm(v1); if ( denom == Scalar(0)) { return 0; @@ -470,7 +499,7 @@ public: Normal in_vec, out_vec; calc_edge_vector(_in_heh, in_vec); calc_edge_vector(next_halfedge_handle(_in_heh), out_vec); - Scalar denom = in_vec.norm()*out_vec.norm(); + Scalar denom = norm(in_vec)*norm(out_vec); if (is_zero(denom)) { _cos_a = 1; @@ -479,7 +508,7 @@ public: else { _cos_a = dot(in_vec, out_vec)/denom; - _sin_a = cross(in_vec, out_vec).norm()/denom; + _sin_a = norm(cross(in_vec, out_vec))/denom; } } */ @@ -499,7 +528,7 @@ public: { Normal sector_normal; calc_sector_normal(_in_heh, sector_normal); - return sector_normal.norm()/2; + return norm(sector_normal)/2; } /** calculates the dihedral angle on the halfedge _heh @@ -539,7 +568,7 @@ public: calc_sector_normal(_heh, n0); calc_sector_normal(this->opposite_halfedge_handle(_heh), n1); calc_edge_vector(_heh, he); - Scalar denom = n0.norm()*n1.norm(); + Scalar denom = norm(n0)*norm(n1); if (denom == Scalar(0)) { return 0; @@ -631,7 +660,7 @@ const LHS mesh_cast(const PolyMeshT *rhs) { //============================================================================= #if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_POLYMESH_C) # define OPENMESH_POLYMESH_TEMPLATES -# include "PolyMeshT.cc" +# include "PolyMeshT_impl.hh" #endif //============================================================================= #endif // OPENMESH_POLYMESHT_HH defined diff --git a/src/OpenMesh/Core/Mesh/PolyMeshT.cc b/src/OpenMesh/Core/Mesh/PolyMeshT_impl.hh similarity index 80% rename from src/OpenMesh/Core/Mesh/PolyMeshT.cc rename to src/OpenMesh/Core/Mesh/PolyMeshT_impl.hh index 827306dc..dabdacfe 100644 --- a/src/OpenMesh/Core/Mesh/PolyMeshT.cc +++ b/src/OpenMesh/Core/Mesh/PolyMeshT_impl.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= @@ -139,18 +134,18 @@ PolyMeshT::calc_face_normal_impl(FaceHandle _fh, PointIs3DTag) const // Due to traits, the value types of normals and points can be different. // Therefore we cast them here. - n[0] += static_cast(a[1] * b[2]); - n[1] += static_cast(a[2] * b[0]); - n[2] += static_cast(a[0] * b[1]); + n[0] += static_cast::value_type>(a[1] * b[2]); + n[1] += static_cast::value_type>(a[2] * b[0]); + n[2] += static_cast::value_type>(a[0] * b[1]); } - const typename vector_traits::value_type norm = n.length(); + const typename vector_traits::value_type length = norm(n); // The expression ((n *= (1.0/norm)),n) is used because the OpenSG // vector class does not return self after component-wise // self-multiplication with a scalar!!! - return (norm != typename vector_traits::value_type(0)) - ? ((n *= (typename vector_traits::value_type(1)/norm)), n) + return (length != typename vector_traits::value_type(0)) + ? ((n *= (typename vector_traits::value_type(1)/length)), n) : Normal(0, 0, 0); } @@ -159,7 +154,15 @@ typename PolyMeshT::Normal PolyMeshT::calc_face_normal_impl(FaceHandle, PointIsNot3DTag) const { // Dummy fallback implementation - return Normal(typename Normal::value_type(0)); + // Returns just an initialized all 0 normal + // This function is only used if we don't have a matching implementation + // for normal computation with the current vector type defined in the mesh traits + + assert(false); + + Normal normal; + vectorize(normal,Scalar(0)); + return normal; } //----------------------------------------------------------------------------- @@ -178,6 +181,14 @@ calc_face_normal(const Point& _p0, >::Result()); } +template +typename PolyMeshT::Normal +PolyMeshT:: +calc_normal(FaceHandle _fh) const +{ + return calc_face_normal(_fh); +} + template typename PolyMeshT::Normal PolyMeshT:: @@ -194,20 +205,22 @@ calc_face_normal_impl(const Point& _p0, Normal p1p2(vector_cast(_p2)); p1p2 -= vector_cast(_p1); Normal n = cross(p1p2, p1p0); - typename vector_traits::value_type norm = n.length(); + typename vector_traits::value_type length = norm(n); // The expression ((n *= (1.0/norm)),n) is used because the OpenSG // vector class does not return self after component-wise // self-multiplication with a scalar!!! - return (norm != typename vector_traits::value_type(0)) ? ((n *= (typename vector_traits::value_type(1)/norm)),n) : Normal(0,0,0); + return (length != typename vector_traits::value_type(0)) + ? ((n *= (typename vector_traits::value_type(1)/length)),n) + : Normal(0,0,0); #else Point p1p0 = _p0; p1p0 -= _p1; Point p1p2 = _p2; p1p2 -= _p1; Normal n = vector_cast(cross(p1p2, p1p0)); - typename vector_traits::value_type norm = n.length(); + typename vector_traits::value_type length = norm(n); - return (norm != 0.0) ? n *= (1.0/norm) : Normal(0,0,0); + return (length != 0.0) ? n *= (1.0/length) : Normal(0,0,0); #endif } @@ -215,7 +228,17 @@ template typename PolyMeshT::Normal PolyMeshT::calc_face_normal_impl(const Point&, const Point&, const Point&, PointIsNot3DTag) const { - return Normal(typename Normal::value_type(0)); + + // Dummy fallback implementation + // Returns just an initialized all 0 normal + // This function is only used if we don't have a matching implementation + // for normal computation with the current vector type defined in the mesh traits + + assert(false); + + Normal normal; + vectorize(normal,Scalar(0)); + return normal; } //----------------------------------------------------------------------------- @@ -226,7 +249,7 @@ PolyMeshT:: calc_face_centroid(FaceHandle _fh) const { Point _pt; - _pt.vectorize(0); + vectorize(_pt, Scalar(0)); Scalar valence = 0.0; for (ConstFaceVertexIter cfv_it = this->cfv_iter(_fh); cfv_it.is_valid(); ++cfv_it, valence += 1.0) { @@ -235,8 +258,58 @@ calc_face_centroid(FaceHandle _fh) const _pt /= valence; return _pt; } + //----------------------------------------------------------------------------- +template +typename PolyMeshT::Point +PolyMeshT:: +calc_centroid(FaceHandle _fh) const +{ + return calc_face_centroid(_fh); +} + +//----------------------------------------------------------------------------- + +template +typename PolyMeshT::Point +PolyMeshT:: +calc_centroid(EdgeHandle _eh) const +{ + return this->calc_edge_midpoint(_eh); +} + +//----------------------------------------------------------------------------- + +template +typename PolyMeshT::Point +PolyMeshT:: +calc_centroid(HalfedgeHandle _heh) const +{ + return this->calc_edge_midpoint(this->edge_handle(_heh)); +} + +//----------------------------------------------------------------------------- + +template +typename PolyMeshT::Point +PolyMeshT:: +calc_centroid(VertexHandle _vh) const +{ + return this->point(_vh); +} + +//----------------------------------------------------------------------------- + +template +typename PolyMeshT::Point +PolyMeshT:: +calc_centroid(MeshHandle /*_mh*/) const +{ + return this->vertices().avg(getPointsProperty(*this)); +} + +//----------------------------------------------------------------------------- template void @@ -331,7 +404,7 @@ calc_halfedge_normal(HalfedgeHandle _heh, const double _feature_angle) const for(unsigned int i=0; i +typename PolyMeshT::Normal +PolyMeshT:: +calc_normal(HalfedgeHandle _heh, const double _feature_angle) const +{ + return calc_halfedge_normal(_heh, _feature_angle); +} + + +//----------------------------------------------------------------------------- + + template bool PolyMeshT:: @@ -378,8 +463,8 @@ calc_vertex_normal(VertexHandle _vh) const Normal n; calc_vertex_normal_fast(_vh,n); - Scalar norm = n.length(); - if (norm != 0.0) n *= (Scalar(1.0)/norm); + Scalar length = norm(n); + if (length != 0.0) n *= (Scalar(1.0)/length); return n; } @@ -389,7 +474,7 @@ template void PolyMeshT:: calc_vertex_normal_fast(VertexHandle _vh, Normal& _n) const { - _n.vectorize(0.0); + vectorize(_n, Scalar(0)); for (ConstVertexFaceIter vf_it = this->cvf_iter(_vh); vf_it.is_valid(); ++vf_it) _n += this->normal(*vf_it); } @@ -399,7 +484,7 @@ template void PolyMeshT:: calc_vertex_normal_correct(VertexHandle _vh, Normal& _n) const { - _n.vectorize(0.0); + vectorize(_n, Scalar(0)); ConstVertexIHalfedgeIter cvih_it = this->cvih_iter(_vh); if (! cvih_it.is_valid() ) {//don't crash on isolated vertices @@ -420,6 +505,9 @@ calc_vertex_normal_correct(VertexHandle _vh, Normal& _n) const in_he_vec = out_he_vec; in_he_vec *= -1;//change the orientation } + Scalar length = norm(_n); + if (length != 0.0) + _n *= (Scalar(1.0)/length); } //----------------------------------------------------------------------------- @@ -444,6 +532,17 @@ calc_vertex_normal_loop(VertexHandle _vh, Normal& _n) const //----------------------------------------------------------------------------- +template +typename PolyMeshT::Normal +PolyMeshT:: +calc_normal(VertexHandle _vh) const +{ + Normal n; + calc_vertex_normal_correct(_vh, n); + return n; +} + +//----------------------------------------------------------------------------- template void diff --git a/src/OpenMesh/Core/Mesh/PolyMesh_ArrayKernelT.hh b/src/OpenMesh/Core/Mesh/PolyMesh_ArrayKernelT.hh index d884ae0b..5111faff 100644 --- a/src/OpenMesh/Core/Mesh/PolyMesh_ArrayKernelT.hh +++ b/src/OpenMesh/Core/Mesh/PolyMesh_ArrayKernelT.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= @@ -102,7 +97,7 @@ class PolyMesh_ArrayKernelT public: PolyMesh_ArrayKernelT() {} template - PolyMesh_ArrayKernelT( const TriMesh_ArrayKernelT & t) + explicit PolyMesh_ArrayKernelT( const TriMesh_ArrayKernelT & t) { //assign the connectivity and standard properties this->assign(t, true); diff --git a/src/OpenMesh/Core/Mesh/SmartHandles.hh b/src/OpenMesh/Core/Mesh/SmartHandles.hh new file mode 100644 index 00000000..094a699f --- /dev/null +++ b/src/OpenMesh/Core/Mesh/SmartHandles.hh @@ -0,0 +1,357 @@ +/* ========================================================================= * + * * + * OpenMesh * + * Copyright (c) 2001-2019, RWTH-Aachen University * + * Department of Computer Graphics and Multimedia * + * All rights reserved. * + * www.openmesh.org * + * * + *---------------------------------------------------------------------------* + * This file is part of OpenMesh. * + *---------------------------------------------------------------------------* + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * 1. Redistributions of source code must retain the above copyright notice, * + * this list of conditions and the following disclaimer. * + * * + * 2. Redistributions in binary form must reproduce the above copyright * + * notice, this list of conditions and the following disclaimer in the * + * documentation and/or other materials provided with the distribution. * + * * + * 3. Neither the name of the copyright holder nor the names of its * + * contributors may be used to endorse or promote products derived from * + * this software without specific prior written permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER * + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * + * * + * ========================================================================= */ + +#ifndef OPENMESH_POLYCONNECTIVITY_INTERFACE_INCLUDE +#error Do not include this directly, include instead PolyConnectivity.hh +#endif//OPENMESH_POLYCONNECTIVITY_INTERFACE_INCLUDE + +//== NAMESPACES =============================================================== + +namespace OpenMesh { + +//== FORWARD DECLARATION ====================================================== + +struct SmartVertexHandle; +struct SmartHalfedgeHandle; +struct SmartEdgeHandle; +struct SmartFaceHandle; + + +//== CLASS DEFINITION ========================================================= + +/// Base class for all smart handle types +class OPENMESHDLLEXPORT SmartBaseHandle +{ +public: + explicit SmartBaseHandle(const PolyConnectivity* _mesh = nullptr) : mesh_(_mesh) {} + + /// Get the underlying mesh of this handle + const PolyConnectivity* mesh() const { return mesh_; } + + // TODO: should operators ==, !=, < look at mesh_? + +private: + const PolyConnectivity* mesh_; + +}; + +/// Smart version of VertexHandle contains a pointer to the corresponding mesh and allows easier access to navigation methods +struct OPENMESHDLLEXPORT SmartVertexHandle : public SmartBaseHandle, VertexHandle +{ + explicit SmartVertexHandle(int _idx=-1, const PolyConnectivity* _mesh = nullptr) : SmartBaseHandle(_mesh), VertexHandle(_idx) {} + + /// Returns an outgoing halfedge + SmartHalfedgeHandle out() const; + /// Returns an outgoing halfedge + SmartHalfedgeHandle halfedge() const; // alias for out + /// Returns an incoming halfedge + SmartHalfedgeHandle in() const; + + /// Returns a range of faces incident to the vertex (PolyConnectivity::vf_range()) + PolyConnectivity::ConstVertexFaceRange faces() const; + /// Returns a range of edges incident to the vertex (PolyConnectivity::ve_range()) + PolyConnectivity::ConstVertexEdgeRange edges() const; + /// Returns a range of vertices adjacent to the vertex (PolyConnectivity::vv_range()) + PolyConnectivity::ConstVertexVertexRange vertices() const; + /// Returns a range of outgoing halfedges incident to the vertex (PolyConnectivity::voh_range()) + PolyConnectivity::ConstVertexIHalfedgeRange incoming_halfedges() const; + /// Returns a range of incoming halfedges incident to the vertex (PolyConnectivity::vih_range()) + PolyConnectivity::ConstVertexOHalfedgeRange outgoing_halfedges() const; + + /// Returns valence of the vertex + uint valence() const; + /// Returns true iff the vertex is incident to a boundary halfedge + bool is_boundary() const; + /// Returns true iff (the mesh at) the vertex is two-manifold ? + bool is_manifold() const; +}; + +struct OPENMESHDLLEXPORT SmartHalfedgeHandle : public SmartBaseHandle, HalfedgeHandle +{ + explicit SmartHalfedgeHandle(int _idx=-1, const PolyConnectivity* _mesh = nullptr) : SmartBaseHandle(_mesh), HalfedgeHandle(_idx) {} + + /// Returns next halfedge handle + SmartHalfedgeHandle next() const; + /// Returns previous halfedge handle + SmartHalfedgeHandle prev() const; + /// Returns opposite halfedge handle + SmartHalfedgeHandle opp() const; + /// Returns vertex pointed to by halfedge + SmartVertexHandle to() const; + /// Returns vertex at start of halfedge + SmartVertexHandle from() const; + /// Returns incident edge of halfedge + SmartEdgeHandle edge() const; + /// Returns incident face of halfedge + SmartFaceHandle face() const; + + /// Returns true iff the halfedge is on the boundary (i.e. it has no corresponding face) + bool is_boundary() const; +}; + +struct OPENMESHDLLEXPORT SmartEdgeHandle : public SmartBaseHandle, EdgeHandle +{ + explicit SmartEdgeHandle(int _idx=-1, const PolyConnectivity* _mesh = nullptr) : SmartBaseHandle(_mesh), EdgeHandle(_idx) {} + + /// Returns one of the two halfedges of the edge + SmartHalfedgeHandle halfedge(unsigned int _i) const; + /// Shorthand for halfedge() + SmartHalfedgeHandle h(unsigned int _i) const; + /// Shorthand for halfedge(0) + SmartHalfedgeHandle h0() const; + /// Shorthand for halfedge(1) + SmartHalfedgeHandle h1() const; + /// Returns one of the two incident vertices of the edge + SmartVertexHandle vertex(unsigned int _i) const; + /// Shorthand for vertex() + SmartVertexHandle v(unsigned int _i) const; + /// Shorthand for vertex(0) + SmartVertexHandle v0() const; + /// Shorthand for vertex(1) + SmartVertexHandle v1() const; + + /// Returns true iff the edge lies on the boundary (i.e. one of the halfedges is boundary) + bool is_boundary() const; +}; + +struct OPENMESHDLLEXPORT SmartFaceHandle : public SmartBaseHandle, FaceHandle +{ + explicit SmartFaceHandle(int _idx=-1, const PolyConnectivity* _mesh = nullptr) : SmartBaseHandle(_mesh), FaceHandle(_idx) {} + + /// Returns one of the halfedges of the face + SmartHalfedgeHandle halfedge() const; + + /// Returns a range of vertices incident to the face (PolyConnectivity::fv_range()) + PolyConnectivity::ConstFaceVertexRange vertices() const; + /// Returns a range of halfedges of the face (PolyConnectivity::fh_range()) + PolyConnectivity::ConstFaceHalfedgeRange halfedges() const; + /// Returns a range of edges of the face (PolyConnectivity::fv_range()) + PolyConnectivity::ConstFaceEdgeRange edges() const; + /// Returns a range adjacent faces of the face (PolyConnectivity::ff_range()) + PolyConnectivity::ConstFaceFaceRange faces() const; + + /// Returns the valence of the face + uint valence() const; + /// Returns true iff the face lies at the boundary (i.e. one of the edges is boundary) + bool is_boundary() const; +}; + + +/// Creats a SmartVertexHandle from a VertexHandle and a Mesh +inline SmartVertexHandle make_smart(VertexHandle _vh, const PolyConnectivity* _mesh) { return SmartVertexHandle (_vh.idx(), _mesh); } +/// Creats a SmartHalfedgeHandle from a HalfedgeHandle and a Mesh +inline SmartHalfedgeHandle make_smart(HalfedgeHandle _hh, const PolyConnectivity* _mesh) { return SmartHalfedgeHandle(_hh.idx(), _mesh); } +/// Creats a SmartEdgeHandle from an EdgeHandle and a Mesh +inline SmartEdgeHandle make_smart(EdgeHandle _eh, const PolyConnectivity* _mesh) { return SmartEdgeHandle (_eh.idx(), _mesh); } +/// Creats a SmartFaceHandle from a FaceHandle and a Mesh +inline SmartFaceHandle make_smart(FaceHandle _fh, const PolyConnectivity* _mesh) { return SmartFaceHandle (_fh.idx(), _mesh); } + +/// Creats a SmartVertexHandle from a VertexHandle and a Mesh +inline SmartVertexHandle make_smart(VertexHandle _vh, const PolyConnectivity& _mesh) { return SmartVertexHandle (_vh.idx(), &_mesh); } +/// Creats a SmartHalfedgeHandle from a HalfedgeHandle and a Mesh +inline SmartHalfedgeHandle make_smart(HalfedgeHandle _hh, const PolyConnectivity& _mesh) { return SmartHalfedgeHandle(_hh.idx(), &_mesh); } +/// Creats a SmartEdgeHandle from an EdgeHandle and a Mesh +inline SmartEdgeHandle make_smart(EdgeHandle _eh, const PolyConnectivity& _mesh) { return SmartEdgeHandle (_eh.idx(), &_mesh); } +/// Creats a SmartFaceHandle from a FaceHandle and a Mesh +inline SmartFaceHandle make_smart(FaceHandle _fh, const PolyConnectivity& _mesh) { return SmartFaceHandle (_fh.idx(), &_mesh); } + + +// helper to convert Handle Types to Smarthandle Types +template +struct SmartHandle; + +template <> struct SmartHandle { using type = SmartVertexHandle; }; +template <> struct SmartHandle { using type = SmartHalfedgeHandle; }; +template <> struct SmartHandle { using type = SmartEdgeHandle; }; +template <> struct SmartHandle { using type = SmartFaceHandle; }; + + +inline SmartHalfedgeHandle SmartVertexHandle::out() const +{ + assert(mesh() != nullptr); + return make_smart(mesh()->halfedge_handle(*this), mesh()); +} + +inline SmartHalfedgeHandle SmartVertexHandle::halfedge() const +{ + return out(); +} + +inline SmartHalfedgeHandle SmartVertexHandle::in() const +{ + return out().opp(); +} + +inline uint SmartVertexHandle::valence() const +{ + assert(mesh() != nullptr); + return mesh()->valence(*this); +} + +inline bool SmartVertexHandle::is_boundary() const +{ + assert(mesh() != nullptr); + return mesh()->is_boundary(*this); +} + +inline bool SmartVertexHandle::is_manifold() const +{ + assert(mesh() != nullptr); + return mesh()->is_manifold(*this); +} + +inline SmartHalfedgeHandle SmartHalfedgeHandle::next() const +{ + assert(mesh() != nullptr); + return make_smart(mesh()->next_halfedge_handle(*this), mesh()); +} + +inline SmartHalfedgeHandle SmartHalfedgeHandle::prev() const +{ + assert(mesh() != nullptr); + return make_smart(mesh()->prev_halfedge_handle(*this), mesh()); +} + +inline SmartHalfedgeHandle SmartHalfedgeHandle::opp() const +{ + assert(mesh() != nullptr); + return make_smart(mesh()->opposite_halfedge_handle(*this), mesh()); +} + +inline SmartVertexHandle SmartHalfedgeHandle::to() const +{ + assert(mesh() != nullptr); + return make_smart(mesh()->to_vertex_handle(*this), mesh()); +} + +inline SmartVertexHandle SmartHalfedgeHandle::from() const +{ + assert(mesh() != nullptr); + return make_smart(mesh()->from_vertex_handle(*this), mesh()); +} + +inline SmartEdgeHandle SmartHalfedgeHandle::edge() const +{ + assert(mesh() != nullptr); + return make_smart(mesh()->edge_handle(*this), mesh()); +} + +inline SmartFaceHandle SmartHalfedgeHandle::face() const +{ + assert(mesh() != nullptr); + return make_smart(mesh()->face_handle(*this), mesh()); +} + +inline bool SmartHalfedgeHandle::is_boundary() const +{ + assert(mesh() != nullptr); + return mesh()->is_boundary(*this); +} + +inline SmartHalfedgeHandle SmartEdgeHandle::halfedge(unsigned int _i) const +{ + assert(mesh() != nullptr); + return make_smart(mesh()->halfedge_handle(*this, _i), mesh()); +} + +inline SmartHalfedgeHandle SmartEdgeHandle::h(unsigned int _i) const +{ + return halfedge(_i); +} + +inline SmartHalfedgeHandle SmartEdgeHandle::h0() const +{ + return h(0); +} + +inline SmartHalfedgeHandle SmartEdgeHandle::h1() const +{ + return h(1); +} + +inline SmartVertexHandle SmartEdgeHandle::vertex(unsigned int _i) const +{ + return halfedge(_i).from(); +} + +inline SmartVertexHandle SmartEdgeHandle::v(unsigned int _i) const +{ + return vertex(_i); +} + +inline SmartVertexHandle SmartEdgeHandle::v0() const +{ + return v(0); +} + +inline SmartVertexHandle SmartEdgeHandle::v1() const +{ + return v(1); +} + +inline bool SmartEdgeHandle::is_boundary() const +{ + assert(mesh() != nullptr); + return mesh()->is_boundary(*this); +} + +inline SmartHalfedgeHandle SmartFaceHandle::halfedge() const +{ + assert(mesh() != nullptr); + return make_smart(mesh()->halfedge_handle(*this), mesh()); +} + +inline uint SmartFaceHandle::valence() const +{ + assert(mesh() != nullptr); + return mesh()->valence(*this); +} + +inline bool SmartFaceHandle::is_boundary() const +{ + assert(mesh() != nullptr); + return mesh()->is_boundary(*this); +} +//============================================================================= +} // namespace OpenMesh +//============================================================================= + +//============================================================================= diff --git a/src/OpenMesh/Core/Mesh/SmartRange.hh b/src/OpenMesh/Core/Mesh/SmartRange.hh new file mode 100644 index 00000000..8f026b19 --- /dev/null +++ b/src/OpenMesh/Core/Mesh/SmartRange.hh @@ -0,0 +1,475 @@ +/* ========================================================================= * + * * + * OpenMesh * + * Copyright (c) 2001-2019, RWTH-Aachen University * + * Department of Computer Graphics and Multimedia * + * All rights reserved. * + * www.openmesh.org * + * * + *---------------------------------------------------------------------------* + * This file is part of OpenMesh. * + *---------------------------------------------------------------------------* + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * 1. Redistributions of source code must retain the above copyright notice, * + * this list of conditions and the following disclaimer. * + * * + * 2. Redistributions in binary form must reproduce the above copyright * + * notice, this list of conditions and the following disclaimer in the * + * documentation and/or other materials provided with the distribution. * + * * + * 3. Neither the name of the copyright holder nor the names of its * + * contributors may be used to endorse or promote products derived from * + * this software without specific prior written permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER * + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * + * * + * ========================================================================= */ + + +#pragma once + +#include +#include +#include +#include + +//== NAMESPACES =============================================================== + +namespace OpenMesh { + +//== FORWARD DECLARATION ====================================================== + +//== CLASS DEFINITION ========================================================= + +namespace { + +struct Identity +{ + template + T operator()(const T& _t) const { return _t; } +}; + +} + +template +struct FilteredSmartRangeT; + +/// Base class for all smart range types +template +struct SmartRangeT +{ + using Handle = HandleT; + using SmartRange = SmartRangeT; + using Range = RangeT; + + // TODO: Someone with better c++ knowledge may improve the code below. + + /** @brief Computes the sum of elements. + * + * Computes the sum of all elements in the range after applying the functor \p f. + * + * @param f Functor that is applied to all elements before computing the sum + */ + template + auto sum(Functor&& f) -> typename std::decay()))>::type + { + auto range = static_cast(this); + auto begin = range->begin(); + auto end = range->end(); + assert(begin != end); + typename std::decay::type result = f(*begin); + auto it = begin; + ++it; + for (; it != end; ++it) + result += f(*it); + return result; + } + + /** @brief Computes the average of elements. + * + * Computes the average of all elements in the range after applying the functor \p f. + * + * @param f Functor that is applied to all elements before computing the average. + */ + template + auto avg(Functor&& f) -> typename std::decay()))>::type + { + auto range = static_cast(this); + auto begin = range->begin(); + auto end = range->end(); + assert(begin != end); + typename std::decay::type result = f(*begin); + auto it = begin; + ++it; + int n_elements = 1; + for (; it != end; ++it) + { + result += f(*it); + ++n_elements; + } + return (1.0 / n_elements) * result; + } + + /** @brief Check if any element fulfils condition. + * + * Checks if functor \p f returns true for any of the elements in the range. + * Returns true if that is the case, false otherwise. + * + * @param f Functor that is evaluated for all elements. + */ + template + auto any_of(Functor&& f) -> bool + { + auto range = static_cast(this); + for (auto e : *range) + if (f(e)) + return true; + return false; + } + + /** @brief Check if all elements fulfil condition. + * + * Checks if functor \p f returns true for all of the elements in the range. + * Returns true if that is the case, false otherwise. + * + * @param f Functor that is evaluated for all elements. + */ + template + auto all_of(Functor&& f) -> bool + { + auto range = static_cast(this); + for (auto e : *range) + if (!f(e)) + return false; + return true; + } + + /** @brief Convert range to array. + * + * Converts the range of elements into an array of objects returned by functor \p f. + * The size of the array needs to be provided by the user. If the size is larger than the number of + * elements in the range, the remaining entries of the array will be uninitialized. + * + * @param f Functor that is applied to all elements before putting them into the array. If no functor is provided + * the array will contain the handles. + */ + template + auto to_array(Functor&& f = {}) -> std::array()))>::type, n> + { + auto range = static_cast(this); + std::array()))>::type, n> res; + auto it = range->begin(); + auto end = range->end(); + int i = 0; + while (i < n && it != end) + res[i++] = f(*(it++)); + return res; + } + + /** @brief Convert range to vector. + * + * Converts the range of elements into a vector of objects returned by functor \p f. + * + * @param f Functor that is applied to all elements before putting them into the vector. If no functor is provided + * the vector will contain the handles. + */ + template + auto to_vector(Functor&& f = {}) -> std::vector()))>::type> + { + auto range = static_cast(this); + std::vector()))>::type> res; + for (const auto& e : *range) + res.push_back(f(e)); + return res; + } + + /** @brief Convert range to set. + * + * Converts the range of elements into a set of objects returned by functor \p f. + * + * @param f Functor that is applied to all elements before putting them into the set. If no functor is provided + * the set will contain the handles. + */ + template + auto to_set(Functor&& f = {}) -> std::set()))>::type> + { + auto range = static_cast(this); + std::set()))>::type> res; + for (const auto& e : *range) + res.insert(f(e)); + return res; + } + + /** @brief Get the first element that fulfills a condition. + * + * Finds the first element of the range for which the functor \p f evaluates to true. + * Returns an invalid handle if none evaluates to true + * + * @param f Functor that is applied to all elements before putting them into the set. If no functor is provided + * the set will contain the handles. + */ + template + auto first(Functor&& f = {}) -> HandleT + { + auto range = static_cast(this); + for (const auto& e : *range) + if (f(e)) + return e; + return HandleT(); + } + + /** @brief Compute minimum. + * + * Computes the minimum of all objects returned by functor \p f. + * + * @param f Functor that is applied to all elements before computing minimum. + */ + template + auto min(Functor&& f) -> typename std::decay()))>::type + { + using std::min; + + auto range = static_cast(this); + auto it = range->begin(); + auto end = range->end(); + assert(it != end); + + typename std::decay()))>::type res = f(*it); + ++it; + + for (; it != end; ++it) + res = min(res, f(*it)); + + return res; + } + + /** @brief Compute minimal element. + * + * Computes the element that minimizes \p f. + * + * @param f Functor that is applied to all elements before comparing. + */ + template + auto argmin(Functor&& f) -> HandleT + { + auto range = static_cast(this); + auto it = range->begin(); + auto min_it = it; + auto end = range->end(); + assert(it != end); + + typename std::decay()))>::type curr_min = f(*it); + ++it; + + for (; it != end; ++it) + { + auto val = f(*it); + if (val < curr_min) + { + curr_min = val; + min_it = it; + } + } + + return *min_it; + } + + /** @brief Compute maximum. + * + * Computes the maximum of all objects returned by functor \p f. + * + * @param f Functor that is applied to all elements before computing maximum. + */ + template + auto max(Functor&& f) -> typename std::decay()))>::type + { + using std::max; + + auto range = static_cast(this); + auto it = range->begin(); + auto end = range->end(); + assert(it != end); + + typename std::decay()))>::type res = f(*it); + ++it; + + for (; it != end; ++it) + res = max(res, f(*it)); + + return res; + } + + + /** @brief Compute maximal element. + * + * Computes the element that maximizes \p f. + * + * @param f Functor that is applied to all elements before comparing. + */ + template + auto argmax(Functor&& f) -> HandleT + { + auto range = static_cast(this); + auto it = range->begin(); + auto max_it = it; + auto end = range->end(); + assert(it != end); + + typename std::decay()))>::type curr_max = f(*it); + ++it; + + for (; it != end; ++it) + { + auto val = f(*it); + if (val > curr_max) + { + curr_max = val; + max_it = it; + } + } + + return *max_it; + } + + /** @brief Computes minimum and maximum. + * + * Computes the minimum and maximum of all objects returned by functor \p f. Result is returned as std::pair + * containing minimum as first and maximum as second element. + * + * @param f Functor that is applied to all elements before computing maximum. + */ + template + auto minmax(Functor&& f) -> std::pair()))>::type, + typename std::decay()))>::type> + { + return std::make_pair(this->min(f), this->max(f)); + } + + + /** @brief Compute number of elements that satisfy a given predicate. + * + * Computes the numer of elements which satisfy functor \p f. + * + * @param f Predicate that elements have to satisfy in order to be counted. + */ + template + auto count_if(Functor&& f) -> int + { + int count = 0; + auto range = static_cast(this); + for (const auto& e : *range) + if (f(e)) + ++count; + return count; + } + + + /** @brief Apply a functor to each element. + * + * Calls functor \p f with each element as parameter + * + * @param f Functor that is called for each element. + */ + template + auto for_each(Functor&& f) -> void + { + auto range = static_cast(this); + for (const auto& e : *range) + f(e); + } + + + /** @brief Only iterate over a subset of elements + * + * Returns a smart range which skips all elements that do not satisfy functor \p f + * + * @param f Functor that needs to be evaluated to true if the element should not be skipped. + */ + template + auto filtered(Functor&& f) -> FilteredSmartRangeT::type> + { + auto range = static_cast(this); + auto b = (*range).begin(); + auto e = (*range).end(); + return FilteredSmartRangeT::type>(f, b, e); + } + + /** @brief Only iterate over a subset of elements + * + * Returns a smart range which skips all elements that do not satisfy functor \p f + * + * @param f Functor that needs to be evaluated to true if the element should not be skipped. + */ + template + auto filtered(Functor& f) -> FilteredSmartRangeT::type&> + { + auto range = static_cast(this); + auto b = (*range).begin(); + auto e = (*range).end(); + return FilteredSmartRangeT::type&>(f, b, e); + } +}; + + +/// Class which applies a filter when iterating over elements +template +struct FilteredSmartRangeT : public SmartRangeT, HandleT> +{ + using BaseRange = SmartRangeT, HandleT>; + using BaseIterator = decltype((std::declval().begin())); + + struct FilteredIterator : public BaseIterator + { + + FilteredIterator(Functor f, BaseIterator it, BaseIterator end): BaseIterator(it), f_(f), end_(end) + { + if (!BaseIterator::operator==(end_) && !f_(*(*this))) // if start is not valid go to first valid one + operator++(); + } + + FilteredIterator& operator++() + { + if (BaseIterator::operator==(end_)) // don't go past end + return *this; + + // go to next valid one + do + BaseIterator::operator++(); + while (BaseIterator::operator!=(end_) && !f_(*(*this))); + return *this; + } + + Functor f_; + BaseIterator end_; + }; + + FilteredSmartRangeT(Functor f, BaseIterator begin, BaseIterator end) : f_(f), begin_(begin), end_(end){} + FilteredIterator begin() const { return FilteredIterator(f_, begin_, end_); } + FilteredIterator end() const { return FilteredIterator(f_, end_, end_); } + + Functor f_; + BaseIterator begin_; + BaseIterator end_; +}; + + + +//============================================================================= +} // namespace OpenMesh +//============================================================================= + +//============================================================================= diff --git a/src/OpenMesh/Core/Mesh/Status.hh b/src/OpenMesh/Core/Mesh/Status.hh index 19e474dc..22ef81d6 100644 --- a/src/OpenMesh/Core/Mesh/Status.hh +++ b/src/OpenMesh/Core/Mesh/Status.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= diff --git a/src/OpenMesh/Core/Mesh/Tags.hh b/src/OpenMesh/Core/Mesh/Tags.hh new file mode 100644 index 00000000..ba3d9a96 --- /dev/null +++ b/src/OpenMesh/Core/Mesh/Tags.hh @@ -0,0 +1,52 @@ +/* ========================================================================= * + * * + * OpenMesh * + * Copyright (c) 2001-2015, RWTH-Aachen University * + * Department of Computer Graphics and Multimedia * + * All rights reserved. * + * www.openmesh.org * + * * + *---------------------------------------------------------------------------* + * This file is part of OpenMesh. * + *---------------------------------------------------------------------------* + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * 1. Redistributions of source code must retain the above copyright notice, * + * this list of conditions and the following disclaimer. * + * * + * 2. Redistributions in binary form must reproduce the above copyright * + * notice, this list of conditions and the following disclaimer in the * + * documentation and/or other materials provided with the distribution. * + * * + * 3. Neither the name of the copyright holder nor the names of its * + * contributors may be used to endorse or promote products derived from * + * this software without specific prior written permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER * + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * + * * + * ========================================================================= */ + +#pragma once + +namespace OpenMesh { + +/// Connectivity tag indicating that the tagged mesh has polygon connectivity. +struct PolyConnectivityTag {}; +/// Connectivity tag indicating that the tagged mesh has triangle connectivity. +struct TriConnectivityTag {}; + +} // namespace OpenMesh + diff --git a/src/OpenMesh/Core/Mesh/Traits.hh b/src/OpenMesh/Core/Mesh/Traits.hh index a0fbe01c..5768286a 100644 --- a/src/OpenMesh/Core/Mesh/Traits.hh +++ b/src/OpenMesh/Core/Mesh/Traits.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + /** \file Core/Mesh/Traits.hh @@ -157,6 +152,24 @@ struct DefaultTraits FaceAttributes(0); }; +/** \class DefaultTraitsDouble Traits.hh + + Version of Default Traits that uses double precision for points and + normals as well as floating point vectors for colors + + \see The Mesh docu section on \ref mesh_type. + \see Traits.hh for a list of macros for traits classes. +*/ +struct DefaultTraitsDouble : public DefaultTraits +{ + /// Use double precision points + typedef OpenMesh::Vec3d Point; + /// Use double precision Normals + typedef OpenMesh::Vec3d Normal; + /// Use RGBA Color + typedef OpenMesh::Vec4f Color; +}; + //== CLASS DEFINITION ========================================================= diff --git a/src/OpenMesh/Core/Mesh/TriConnectivity.cc b/src/OpenMesh/Core/Mesh/TriConnectivity.cc index e3d69623..31f63fc3 100644 --- a/src/OpenMesh/Core/Mesh/TriConnectivity.cc +++ b/src/OpenMesh/Core/Mesh/TriConnectivity.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + // CLASS TriMeshT - IMPLEMENTATION @@ -54,11 +49,11 @@ namespace OpenMesh { -TriConnectivity::FaceHandle +SmartFaceHandle TriConnectivity::add_face(const VertexHandle* _vertex_handles, size_t _vhs_size) { // need at least 3 vertices - if (_vhs_size < 3) return InvalidFaceHandle; + if (_vhs_size < 3) return make_smart(InvalidFaceHandle, this); /// face is triangle -> ok if (_vhs_size == 3) @@ -83,21 +78,29 @@ TriConnectivity::add_face(const VertexHandle* _vertex_handles, size_t _vhs_size) fh = PolyConnectivity::add_face(vhandles, 3); } - return fh; + return make_smart(fh, this); } } //----------------------------------------------------------------------------- -FaceHandle TriConnectivity::add_face(const std::vector& _vhandles) +SmartFaceHandle TriConnectivity::add_face(const std::vector& _vhandles) { return add_face(&_vhandles.front(), _vhandles.size()); } //----------------------------------------------------------------------------- +SmartFaceHandle TriConnectivity::add_face(const std::vector& _vhandles) +{ + std::vector vhandles(_vhandles.begin(), _vhandles.end()); + return add_face(&vhandles.front(), vhandles.size()); +} -FaceHandle TriConnectivity::add_face(VertexHandle _vh0, VertexHandle _vh1, VertexHandle _vh2) +//----------------------------------------------------------------------------- + + +SmartFaceHandle TriConnectivity::add_face(VertexHandle _vh0, VertexHandle _vh1, VertexHandle _vh2) { VertexHandle vhs[3] = { _vh0, _vh1, _vh2 }; return PolyConnectivity::add_face(vhs, 3); @@ -488,6 +491,11 @@ void TriConnectivity::split(EdgeHandle _eh, VertexHandle _vh) void TriConnectivity::split_copy(EdgeHandle _eh, VertexHandle _vh) { + const VertexHandle v0 = to_vertex_handle(halfedge_handle(_eh, 0)); + const VertexHandle v1 = to_vertex_handle(halfedge_handle(_eh, 1)); + + const size_t nf = n_faces(); + // Split the halfedge ( handle will be preserved) split(_eh, _vh); @@ -495,6 +503,22 @@ void TriConnectivity::split_copy(EdgeHandle _eh, VertexHandle _vh) // have been created for(VEIter ve_it = ve_iter(_vh); ve_it.is_valid(); ++ve_it) copy_all_properties(_eh, *ve_it, true); + + for (auto vh : {v0, v1}) + { + // get the halfedge pointing from new vertex to old vertex + const HalfedgeHandle h = find_halfedge(_vh, vh); + if (!is_boundary(h)) // for boundaries there are no faces whose properties need to be copied + { + FaceHandle fh0 = face_handle(h); + FaceHandle fh1 = face_handle(opposite_halfedge_handle(prev_halfedge_handle(h))); + if (static_cast(fh0.idx()) >= nf) // is fh0 the new face? + std::swap(fh0, fh1); + + // copy properties from old face to new face + copy_all_properties(fh0, fh1, true); + } + } } }// namespace OpenMesh diff --git a/src/OpenMesh/Core/Mesh/TriConnectivity.hh b/src/OpenMesh/Core/Mesh/TriConnectivity.hh index 197420dd..f9c84751 100644 --- a/src/OpenMesh/Core/Mesh/TriConnectivity.hh +++ b/src/OpenMesh/Core/Mesh/TriConnectivity.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef OPENMESH_TRICONNECTIVITY_HH #define OPENMESH_TRICONNECTIVITY_HH @@ -90,8 +85,8 @@ public: * * * */ - FaceHandle add_face(const VertexHandle* _vhandles, size_t _vhs_size); - + SmartFaceHandle add_face(const VertexHandle* _vhandles, size_t _vhs_size); + /** \brief Add a face with arbitrary valence to the triangle mesh * * Override OpenMesh::Mesh::PolyMeshT::add_face(). Faces that aren't @@ -100,7 +95,17 @@ public: * * * */ - FaceHandle add_face(const std::vector& _vhandles); + SmartFaceHandle add_face(const std::vector& _vhandles); + + /** \brief Add a face with arbitrary valence to the triangle mesh + * + * Override OpenMesh::Mesh::PolyMeshT::add_face(). Faces that aren't + * triangles will be triangulated and added. In this case an + * invalid face handle will be returned. + * + * + * */ + SmartFaceHandle add_face(const std::vector& _vhandles); /** \brief Add a face to the mesh (triangle) * @@ -112,7 +117,7 @@ public: * @param _vh2 VertexHandle 3 * @return FaceHandle of the added face (invalid, if the operation failed) */ - FaceHandle add_face(VertexHandle _vh0, VertexHandle _vh1, VertexHandle _vh2); + SmartFaceHandle add_face(VertexHandle _vh0, VertexHandle _vh1, VertexHandle _vh2); //@} @@ -162,27 +167,63 @@ public: * * \note The properties of the new edges, halfedges, and faces will be undefined! * - * @param _eh Edge handle that should be splitted + * @param _eh Edge handle that should be split * @param _vh Vertex handle that will be inserted at the edge */ void split(EdgeHandle _eh, VertexHandle _vh); + /** \brief Edge split (= 2-to-4 split) + * + * + * The function will introduce two new faces ( non-boundary case) or + * one additional face (if edge is boundary) + * + * \note The properties of the new edges, halfedges, and faces will be undefined! + * + * \note This is an override to prevent a direct call to PolyConnectivity split_edge, + * which would introduce a singular vertex with valence 2 which is not allowed + * on TriMeshes + * + * @param _eh Edge handle that should be split + * @param _vh Vertex handle that will be inserted at the edge + */ + inline void split_edge(EdgeHandle _eh, VertexHandle _vh) { TriConnectivity::split(_eh, _vh); } + /** \brief Edge split (= 2-to-4 split) * * The function will introduce two new faces ( non-boundary case) or * one additional face (if edge is boundary) * - * \note The properties of the new edges will be adjusted to the properties of the original edge - * \note The properties of the new faces and halfedges will be undefined + * \note The properties of the new edges and faces will be adjusted to the + * properties of the original edge and face + * \note The properties of the new halfedges will be undefined * - * @param _eh Edge handle that should be splitted + * @param _eh Edge handle that should be split * @param _vh Vertex handle that will be inserted at the edge */ void split_copy(EdgeHandle _eh, VertexHandle _vh); + /** \brief Edge split (= 2-to-4 split) + * + * The function will introduce two new faces ( non-boundary case) or + * one additional face (if edge is boundary) + * + * \note The properties of the new edges and faces will be adjusted to the + * properties of the original edge and face + * \note The properties of the new halfedges will be undefined + * + * \note This is an override to prevent a direct call to PolyConnectivity split_edge_copy, + * which would introduce a singular vertex with valence 2 which is not allowed + * on TriMeshes + * + * @param _eh Edge handle that should be split + * @param _vh Vertex handle that will be inserted at the edge + */ + inline void split_edge_copy(EdgeHandle _eh, VertexHandle _vh) { TriConnectivity::split_copy(_eh, _vh); } + /** \brief Face split (= 1-to-3) split, calls corresponding PolyMeshT function). * - * @param _fh Face handle that should be splitted + * @param _fh Face handle that should be split * @param _vh Vertex handle that will be inserted at the face */ inline void split(FaceHandle _fh, VertexHandle _vh) @@ -190,7 +231,7 @@ public: /** \brief Face split (= 1-to-3) split, calls corresponding PolyMeshT function). * - * @param _fh Face handle that should be splitted + * @param _fh Face handle that should be split * @param _vh Vertex handle that will be inserted at the face */ inline void split_copy(FaceHandle _fh, VertexHandle _vh) diff --git a/src/OpenMesh/Core/Mesh/TriMeshT.hh b/src/OpenMesh/Core/Mesh/TriMeshT.hh index 6ff32f3c..5784fb2f 100644 --- a/src/OpenMesh/Core/Mesh/TriMeshT.hh +++ b/src/OpenMesh/Core/Mesh/TriMeshT.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= @@ -63,6 +58,7 @@ #include #include +#include #include @@ -103,11 +99,12 @@ public: typedef PolyMeshT PolyMesh; //@{ - /// Determine whether this is a PolyMeshT or TriMeshT ( This function does not check the per face vertex count! It only checks if the datatype is PolyMeshT or TriMeshT ) + /// Determine whether this is a PolyMeshT or TriMeshT (This function does not check the per face vertex count! It only checks if the datatype is PolyMeshT or TriMeshT) + static constexpr bool is_polymesh() { return false; } + static constexpr bool is_trimesh() { return true; } + using ConnectivityTag = TriConnectivityTag; enum { IsPolyMesh = 0 }; enum { IsTriMesh = 1 }; - static bool is_polymesh() { return false; } - static bool is_trimesh() { return true; } //@} //--- items --- @@ -181,9 +178,11 @@ public: /** \brief Vertex Split: inverse operation to collapse(). * * Insert the new vertex at position v0. The vertex will be added - * as the inverse of the vertex split. The faces above the split + * as the inverse of the edge collapse. The faces above the split * will be correctly attached to the two new edges * + *
    +   *
        * Before:
        * v_l     v0     v_r
        *  x      x      x
    @@ -208,6 +207,8 @@ public:
        *         x
        *         v1
        *
    +   * 
    + * * @param _v0_point Point position for the new point * @param _v1 Vertex that will be split * @param _vl Left vertex handle @@ -221,9 +222,11 @@ public: /** \brief Vertex Split: inverse operation to collapse(). * * Insert the new vertex at position v0. The vertex will be added - * as the inverse of the vertex split. The faces above the split + * as the inverse of the edge collapse. The faces above the split * will be correctly attached to the two new edges * + *
    +   *
        * Before:
        * v_l     v0     v_r
        *  x      x      x
    @@ -248,6 +251,8 @@ public:
        *         x
        *         v1
        *
    +   * 
    + * * @param _v0 Vertex handle for the newly inserted point (Input has to be unconnected!) * @param _v1 Vertex that will be split * @param _vl Left vertex handle @@ -267,10 +272,10 @@ public: * @param _p New point position that will be inserted at the edge * @return Vertex handle of the newly added vertex */ - inline VertexHandle split(EdgeHandle _eh, const Point& _p) + inline SmartVertexHandle split(EdgeHandle _eh, const Point& _p) { //Do not call PolyMeshT function below as this does the wrong operation - const VertexHandle vh = this->add_vertex(_p); Kernel::split(_eh, vh); return vh; + const SmartVertexHandle vh = this->add_vertex(_p); Kernel::split(_eh, vh); return vh; } /** \brief Edge split (= 2-to-4 split) @@ -281,10 +286,10 @@ public: * @param _p New point position that will be inserted at the edge * @return Vertex handle of the newly added vertex */ - inline VertexHandle split_copy(EdgeHandle _eh, const Point& _p) + inline SmartVertexHandle split_copy(EdgeHandle _eh, const Point& _p) { //Do not call PolyMeshT function below as this does the wrong operation - const VertexHandle vh = this->add_vertex(_p); Kernel::split_copy(_eh, vh); return vh; + const SmartVertexHandle vh = this->add_vertex(_p); Kernel::split_copy(_eh, vh); return vh; } /** \brief Edge split (= 2-to-4 split) @@ -322,8 +327,8 @@ public: * * @return Vertex handle of the new vertex */ - inline VertexHandle split(FaceHandle _fh, const Point& _p) - { const VertexHandle vh = this->add_vertex(_p); PolyMesh::split(_fh, vh); return vh; } + inline SmartVertexHandle split(FaceHandle _fh, const Point& _p) + { const SmartVertexHandle vh = this->add_vertex(_p); PolyMesh::split(_fh, vh); return vh; } /** \brief Face split (= 1-to-3 split, calls corresponding PolyMeshT function). * @@ -334,8 +339,8 @@ public: * * @return Vertex handle of the new vertex */ - inline VertexHandle split_copy(FaceHandle _fh, const Point& _p) - { const VertexHandle vh = this->add_vertex(_p); PolyMesh::split_copy(_fh, vh); return vh; } + inline SmartVertexHandle split_copy(FaceHandle _fh, const Point& _p) + { const SmartVertexHandle vh = this->add_vertex(_p); PolyMesh::split_copy(_fh, vh); return vh; } /** \brief Face split (= 1-to-4) split, splits edges at midpoints and adds 4 new faces in the interior). @@ -359,9 +364,9 @@ public: VertexHandle p2 = this->to_vertex_handle(he2); // Calculate midpoint coordinates - const Point new0 = (this->point(p0) + this->point(p2)) * static_cast< typename Point::value_type >(0.5); - const Point new1 = (this->point(p0) + this->point(p1)) * static_cast< typename Point::value_type >(0.5); - const Point new2 = (this->point(p1) + this->point(p2)) * static_cast< typename Point::value_type >(0.5); + const Point new0 = (this->point(p0) + this->point(p2)) * static_cast::value_type >(0.5); + const Point new1 = (this->point(p0) + this->point(p1)) * static_cast::value_type >(0.5); + const Point new2 = (this->point(p1) + this->point(p2)) * static_cast::value_type >(0.5); // Add vertices at midpoint coordinates VertexHandle v0 = this->add_vertex(new0); @@ -414,6 +419,16 @@ public: */ inline void split_copy(FaceHandle _fh, VertexHandle _vh) { PolyMesh::split_copy(_fh, _vh); } + + /** \brief Calculates the area of a face + * + * @param _fh Handle of the face to calculate the area of + */ + Scalar calc_face_area(FaceHandle _fh) const + { + const HalfedgeHandle heh = this->halfedge_handle(_fh); + return this->calc_sector_area(heh); + } /** \name Normal vector computation */ @@ -431,7 +446,7 @@ public: //============================================================================= #if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_TRIMESH_C) #define OPENMESH_TRIMESH_TEMPLATES -#include "TriMeshT.cc" +#include "TriMeshT_impl.hh" #endif //============================================================================= #endif // OPENMESH_TRIMESH_HH defined diff --git a/src/OpenMesh/Core/Mesh/TriMeshT.cc b/src/OpenMesh/Core/Mesh/TriMeshT_impl.hh similarity index 90% rename from src/OpenMesh/Core/Mesh/TriMeshT.cc rename to src/OpenMesh/Core/Mesh/TriMeshT_impl.hh index c225cd5a..43592ecc 100644 --- a/src/OpenMesh/Core/Mesh/TriMeshT.cc +++ b/src/OpenMesh/Core/Mesh/TriMeshT_impl.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= diff --git a/src/OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh b/src/OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh index 0c648bf2..21d1654c 100644 --- a/src/OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh +++ b/src/OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= @@ -102,7 +97,7 @@ class TriMesh_ArrayKernelT public: TriMesh_ArrayKernelT() {} template - TriMesh_ArrayKernelT( const PolyMesh_ArrayKernelT & t) + explicit TriMesh_ArrayKernelT( const PolyMesh_ArrayKernelT & t) { //assign the connectivity and standard properties this->assign(t,true); diff --git a/src/OpenMesh/Core/Mesh/gen/circulators_header.hh b/src/OpenMesh/Core/Mesh/gen/circulators_header.hh index 72bab075..276a737b 100644 --- a/src/OpenMesh/Core/Mesh/gen/circulators_header.hh +++ b/src/OpenMesh/Core/Mesh/gen/circulators_header.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef OPENMESH_CIRCULATORS_HH #define OPENMESH_CIRCULATORS_HH diff --git a/src/OpenMesh/Core/Mesh/gen/iterators_header.hh b/src/OpenMesh/Core/Mesh/gen/iterators_header.hh index 22f6d8b6..89205330 100644 --- a/src/OpenMesh/Core/Mesh/gen/iterators_header.hh +++ b/src/OpenMesh/Core/Mesh/gen/iterators_header.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef OPENMESH_ITERATORS_HH #define OPENMESH_ITERATORS_HH diff --git a/src/OpenMesh/Core/System/OpenMeshDLLMacros.hh b/src/OpenMesh/Core/System/OpenMeshDLLMacros.hh index c4d6a292..d821df74 100644 --- a/src/OpenMesh/Core/System/OpenMeshDLLMacros.hh +++ b/src/OpenMesh/Core/System/OpenMeshDLLMacros.hh @@ -39,13 +39,6 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision: 566 $ * - * $Date: 2012-03-23 18:00:57 +0100 (Fr, 23 Mär 2012) $ * - * * -\*===========================================================================*/ - // Disable the warnings about needs to have DLL interface as we have tons of vector templates #ifdef _MSC_VER #pragma warning( disable: 4251 ) diff --git a/src/OpenMesh/Core/System/compiler.hh b/src/OpenMesh/Core/System/compiler.hh index 412b090a..b74ed041 100644 --- a/src/OpenMesh/Core/System/compiler.hh +++ b/src/OpenMesh/Core/System/compiler.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef OPENMESH_COMPILER_H diff --git a/src/OpenMesh/Core/System/config.h b/src/OpenMesh/Core/System/config.h index e0d436e3..a8a5a1fa 100644 --- a/src/OpenMesh/Core/System/config.h +++ b/src/OpenMesh/Core/System/config.h @@ -65,11 +65,8 @@ // ---------------------------------------------------------------------------- -#define OM_VERSION 0x70000 -//#define OM_VERSION 0x60300 - -// only defined, if it is a beta version -//#define OM_VERSION_BETA 4 +#define OM_VERSION 0x90000 +//#define OM_VERSION 0x70200 #define OM_GET_VER ((OM_VERSION & 0xf0000) >> 16) #define OM_GET_MAJ ((OM_VERSION & 0x0ff00) >> 8) @@ -86,18 +83,23 @@ # endif #endif -#if defined(_MSC_VER) -# define DEPRECATED(msg) __declspec(deprecated(msg)) +//! define OM_SUPPRESS_DEPRECATED to suppress deprecated code warnings +#if defined(OM_SUPPRESS_DEPRECATED) +#pragma message( \ + "OpenMesh deprecated code warnings suppressed, please fix your code soon") +# define OM_DEPRECATED(msg) +#elif defined(_MSC_VER) +# define OM_DEPRECATED(msg) __declspec(deprecated(msg)) #elif defined(__GNUC__) # if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= 40500 /* Test for GCC >= 4.5.0 */ -# define DEPRECATED(msg) __attribute__ ((deprecated(msg))) +# define OM_DEPRECATED(msg) __attribute__ ((deprecated(msg))) # else -# define DEPRECATED(msg) __attribute__ ((deprecated)) +# define OM_DEPRECATED(msg) __attribute__ ((deprecated)) # endif #elif defined(__clang__) -# define DEPRECATED(msg) __attribute__ ((deprecated(msg))) +# define OM_DEPRECATED(msg) __attribute__ ((deprecated(msg))) #else -# define DEPRECATED(msg) +# define OM_DEPRECATED(msg) #endif typedef unsigned int uint; diff --git a/src/OpenMesh/Core/System/config.hh b/src/OpenMesh/Core/System/config.hh index 6c23e27e..ba504c55 100644 --- a/src/OpenMesh/Core/System/config.hh +++ b/src/OpenMesh/Core/System/config.hh @@ -39,11 +39,6 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #include diff --git a/src/OpenMesh/Core/System/mostream.hh b/src/OpenMesh/Core/System/mostream.hh index 4dabf51c..e774d7bc 100644 --- a/src/OpenMesh/Core/System/mostream.hh +++ b/src/OpenMesh/Core/System/mostream.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= // @@ -97,7 +92,7 @@ class multiplex_target : public basic_multiplex_target { public: explicit multiplex_target(T& _t) : target_(_t) {} - virtual void operator<<(const std::string& _s) { target_ << _s; } + virtual void operator<<(const std::string& _s) override { target_ << _s; } private: T& target_; }; @@ -290,7 +285,7 @@ class mostream : public std::ostream public: /// Explicit constructor - explicit mostream() : std::ostream(NULL) { init(&streambuffer_); } + explicit mostream() : std::ostream(nullptr) { init(&streambuffer_); } /// Connect target to multiplexer diff --git a/src/OpenMesh/Core/System/omstream.cc b/src/OpenMesh/Core/System/omstream.cc index 79554c15..810e3152 100644 --- a/src/OpenMesh/Core/System/omstream.cc +++ b/src/OpenMesh/Core/System/omstream.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= // diff --git a/src/OpenMesh/Core/System/omstream.hh b/src/OpenMesh/Core/System/omstream.hh index 01fdfb00..b44c5507 100644 --- a/src/OpenMesh/Core/System/omstream.hh +++ b/src/OpenMesh/Core/System/omstream.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= // diff --git a/src/OpenMesh/Core/Templates/newClass.hh b/src/OpenMesh/Core/Templates/bla.hh similarity index 85% rename from src/OpenMesh/Core/Templates/newClass.hh rename to src/OpenMesh/Core/Templates/bla.hh index 31a2fd2f..73403667 100644 --- a/src/OpenMesh/Core/Templates/newClass.hh +++ b/src/OpenMesh/Core/Templates/bla.hh @@ -39,21 +39,16 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= // -// CLASS newClass +// CLASS bla // //============================================================================= #ifndef DOXY_IGNORE_THIS -#ifndef OPENMESH_NEWCLASS_HH -#define OPENMESH_NEWCLASS_HH +#ifndef OPENMESH_NEWCLASST_HH +#define OPENMESH_NEWCLASST_HH //== INCLUDES ================================================================= @@ -69,40 +64,47 @@ namespace OpenMesh { //== CLASS DEFINITION ========================================================= + + -/** \class newClass newClass.hh +/** \class blaT blaT.hh Brief Description. A more elaborate description follows. */ -class newClass +template <> +class blaT { public: /// Default constructor - newClass() {} + blaT() {} /// Destructor - ~newClass() {} + ~blaT() {} - + private: /// Copy constructor (not used) - newClass(const newClass& _rhs); + blaT(const blaT& _rhs); /// Assignment operator (not used) - newClass& operator=(const newClass& _rhs); - + blaT& operator=(const blaT& _rhs); + }; //============================================================================= } // namespace OpenMesh //============================================================================= -#endif // OPENMESH_NEWCLASS_HH defined +#if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_BLA_C) +#define OPENMESH_BLA_TEMPLATES +#include "blaT_impl.hh" +#endif +//============================================================================= +#endif // OPENMESH_NEWCLASST_HH defined #endif // DOXY_IGNORE_THIS //============================================================================= - diff --git a/src/OpenMesh/Core/Templates/newClass.cc b/src/OpenMesh/Core/Templates/blaT_impl.hh similarity index 88% rename from src/OpenMesh/Core/Templates/newClass.cc rename to src/OpenMesh/Core/Templates/blaT_impl.hh index a0f5abab..64c3b6df 100644 --- a/src/OpenMesh/Core/Templates/newClass.cc +++ b/src/OpenMesh/Core/Templates/blaT_impl.hh @@ -39,23 +39,19 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= // -// CLASS newClass - IMPLEMENTATION +// CLASS bla - IMPLEMENTATION // //============================================================================= +#define OPENMESH_BLA_C //== INCLUDES ================================================================= -#include +#include //== NAMESPACES =============================================================== @@ -63,7 +59,7 @@ namespace OpenMesh { -//== IMPLEMENTATION ========================================================== +//== IMPLEMENTATION ========================================================== diff --git a/src/OpenMesh/Core/Templates/newClass.sh b/src/OpenMesh/Core/Templates/newClass.sh deleted file mode 100644 index 7ea19a72..00000000 --- a/src/OpenMesh/Core/Templates/newClass.sh +++ /dev/null @@ -1,9 +0,0 @@ -#! /bin/sh - -A=`echo $1_ | tr '[:lower:]' '[:upper:]'` - -sed -e s/newClass/$1/g -e s/NEWCLASS_/$A/g < newClass.cc > tmp_newClass.cc -sed -e s/newClass/$1/g -e s/NEWCLASS_/$A/g < newClass.hh > tmp_newClass.hh - -mv -i tmp_newClass.cc $1.cc && echo $1.cc - ok -mv -i tmp_newClass.hh $1.hh && echo $1.hh - ok diff --git a/src/OpenMesh/Core/Templates/newClassT.hh b/src/OpenMesh/Core/Templates/newClassT.hh deleted file mode 100644 index 00b5f143..00000000 --- a/src/OpenMesh/Core/Templates/newClassT.hh +++ /dev/null @@ -1,115 +0,0 @@ -/* ========================================================================= * - * * - * OpenMesh * - * Copyright (c) 2001-2015, RWTH-Aachen University * - * Department of Computer Graphics and Multimedia * - * All rights reserved. * - * www.openmesh.org * - * * - *---------------------------------------------------------------------------* - * This file is part of OpenMesh. * - *---------------------------------------------------------------------------* - * * - * Redistribution and use in source and binary forms, with or without * - * modification, are permitted provided that the following conditions * - * are met: * - * * - * 1. Redistributions of source code must retain the above copyright notice, * - * this list of conditions and the following disclaimer. * - * * - * 2. Redistributions in binary form must reproduce the above copyright * - * notice, this list of conditions and the following disclaimer in the * - * documentation and/or other materials provided with the distribution. * - * * - * 3. Neither the name of the copyright holder nor the names of its * - * contributors may be used to endorse or promote products derived from * - * this software without specific prior written permission. * - * * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER * - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * * - * ========================================================================= */ - -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ - -//============================================================================= -// -// CLASS newClass -// -//============================================================================= -#ifndef DOXY_IGNORE_THIS -#ifndef OPENMESH_NEWCLASST_HH -#define OPENMESH_NEWCLASST_HH - - -//== INCLUDES ================================================================= - - -//== FORWARDDECLARATIONS ====================================================== - - -//== NAMESPACES =============================================================== - -namespace OpenMesh { - - -//== CLASS DEFINITION ========================================================= - - - - -/** \class newClassT newClassT.hh - - Brief Description. - - A more elaborate description follows. -*/ - -template <> -class newClassT -{ -public: - - /// Default constructor - newClassT() {} - - /// Destructor - ~newClassT() {} - - -private: - - /// Copy constructor (not used) - newClassT(const newClassT& _rhs); - - /// Assignment operator (not used) - newClassT& operator=(const newClassT& _rhs); - -}; - - -//============================================================================= -} // namespace OpenMesh -//============================================================================= -#if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_NEWCLASS_C) -#define OPENMESH_NEWCLASS_TEMPLATES -#include "newClass.cc" -#endif -//============================================================================= -#endif // OPENMESH_NEWCLASST_HH defined -#endif // DOXY_IGNORE_THIS -//============================================================================= diff --git a/src/OpenMesh/Core/Templates/newClassT.sh b/src/OpenMesh/Core/Templates/newClassT.sh deleted file mode 100644 index 70232447..00000000 --- a/src/OpenMesh/Core/Templates/newClassT.sh +++ /dev/null @@ -1,9 +0,0 @@ -#! /bin/sh - -A=`echo $1_ | tr '[:lower:]' '[:upper:]'` - -sed -e s/newClass/$1/g -e s/NEWCLASS_/$A/g < newClassT.cc > tmp_newClass.cc -sed -e s/newClass/$1/g -e s/NEWCLASS_/$A/g < newClassT.hh > tmp_newClass.hh - -mv -i tmp_newClass.cc $1.cc && echo $1.cc - ok -mv -i tmp_newClass.hh $1.hh && echo $1.hh - ok diff --git a/src/OpenMesh/Core/Utils/AutoPropertyHandleT.hh b/src/OpenMesh/Core/Utils/AutoPropertyHandleT.hh index fae37a94..19afb46e 100644 --- a/src/OpenMesh/Core/Utils/AutoPropertyHandleT.hh +++ b/src/OpenMesh/Core/Utils/AutoPropertyHandleT.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef OPENMESH_AutoPropertyHandleT_HH #define OPENMESH_AutoPropertyHandleT_HH @@ -75,7 +70,7 @@ protected: public: AutoPropertyHandleT() - : m_(NULL), own_property_(false) + : m_(nullptr), own_property_(false) {} AutoPropertyHandleT(const Self& _other) diff --git a/src/OpenMesh/Core/Utils/BaseProperty.cc b/src/OpenMesh/Core/Utils/BaseProperty.cc index 92de7b6b..847b1882 100644 --- a/src/OpenMesh/Core/Utils/BaseProperty.cc +++ b/src/OpenMesh/Core/Utils/BaseProperty.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #include diff --git a/src/OpenMesh/Core/Utils/BaseProperty.hh b/src/OpenMesh/Core/Utils/BaseProperty.hh index 3abcfe2e..1e63d6d3 100644 --- a/src/OpenMesh/Core/Utils/BaseProperty.hh +++ b/src/OpenMesh/Core/Utils/BaseProperty.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef OPENMESH_BASEPROPERTY_HH #define OPENMESH_BASEPROPERTY_HH @@ -85,13 +80,13 @@ public: /// /// \param _name Optional textual name for the property. /// - BaseProperty(const std::string& _name = "") - : name_(_name), persistent_(false) + BaseProperty(const std::string& _name = "", const std::string& _internal_type_name = "" ) + : name_(_name), internal_type_name_(_internal_type_name), persistent_(false) {} /// \brief Copy constructor BaseProperty(const BaseProperty & _rhs) - : name_( _rhs.name_ ), persistent_( _rhs.persistent_ ) {} + : name_( _rhs.name_ ), internal_type_name_(_rhs.internal_type_name_), persistent_( _rhs.persistent_ ) {} /// Destructor. virtual ~BaseProperty() {} @@ -124,6 +119,9 @@ public: // named property interface /// Return the name of the property const std::string& name() const { return name_; } + /// Return internal type name of the property for type safe casting alternative to runtime information + const std::string& internal_type_name() const { return internal_type_name_; } + virtual void stats(std::ostream& _ostr) const; public: // I/O support @@ -178,6 +176,7 @@ protected: private: std::string name_; + std::string internal_type_name_; bool persistent_; }; diff --git a/src/OpenMesh/Core/Utils/Endian.cc b/src/OpenMesh/Core/Utils/Endian.cc index c4fb3146..1af0a81a 100644 --- a/src/OpenMesh/Core/Utils/Endian.cc +++ b/src/OpenMesh/Core/Utils/Endian.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= diff --git a/src/OpenMesh/Core/Utils/Endian.hh b/src/OpenMesh/Core/Utils/Endian.hh index e511c00a..a3b3ce89 100644 --- a/src/OpenMesh/Core/Utils/Endian.hh +++ b/src/OpenMesh/Core/Utils/Endian.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= diff --git a/src/OpenMesh/Core/Utils/GenProg.hh b/src/OpenMesh/Core/Utils/GenProg.hh index bf0b20a3..9d04af21 100644 --- a/src/OpenMesh/Core/Utils/GenProg.hh +++ b/src/OpenMesh/Core/Utils/GenProg.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= diff --git a/src/OpenMesh/Core/Utils/HandleToPropHandle.hh b/src/OpenMesh/Core/Utils/HandleToPropHandle.hh new file mode 100644 index 00000000..6e5f6393 --- /dev/null +++ b/src/OpenMesh/Core/Utils/HandleToPropHandle.hh @@ -0,0 +1,45 @@ +#ifndef HANDLETOPROPHANDLE_HH_ +#define HANDLETOPROPHANDLE_HH_ + +#include +#include + +namespace OpenMesh { + + template + struct HandleToPropHandle { + }; + + template + struct HandleToPropHandle { + using type = OpenMesh::VPropHandleT; + }; + + template + struct HandleToPropHandle { + using type = OpenMesh::HPropHandleT; + }; + + template + struct HandleToPropHandle { + using type = OpenMesh::EPropHandleT; + }; + + template + struct HandleToPropHandle { + using type = OpenMesh::FPropHandleT; + }; + + template + struct HandleToPropHandle { + using type = OpenMesh::MPropHandleT; + }; + + template + struct HandleToPropHandle { + using type = OpenMesh::MPropHandleT; + }; + +} // namespace OpenMesh + +#endif // HANDLETOPROPHANDLE_HH_ diff --git a/src/OpenMesh/Core/Utils/Noncopyable.hh b/src/OpenMesh/Core/Utils/Noncopyable.hh index ddbfb3ed..87f64412 100644 --- a/src/OpenMesh/Core/Utils/Noncopyable.hh +++ b/src/OpenMesh/Core/Utils/Noncopyable.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= diff --git a/src/OpenMesh/Core/Utils/Property.hh b/src/OpenMesh/Core/Utils/Property.hh index ab26d9d3..71e2f86f 100644 --- a/src/OpenMesh/Core/Utils/Property.hh +++ b/src/OpenMesh/Core/Utils/Property.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef OPENMESH_PROPERTY_HH #define OPENMESH_PROPERTY_HH @@ -104,8 +99,10 @@ public: public: /// Default constructor - PropertyT(const std::string& _name = "") - : BaseProperty(_name) + explicit PropertyT( + const std::string& _name = "", + const std::string& _internal_type_name = "") + : BaseProperty(_name, _internal_type_name) {} /// Copy constructor @@ -114,22 +111,22 @@ public: public: // inherited from BaseProperty - virtual void reserve(size_t _n) { data_.reserve(_n); } - virtual void resize(size_t _n) { data_.resize(_n); } - virtual void clear() { data_.clear(); vector_type().swap(data_); } - virtual void push_back() { data_.push_back(T()); } - virtual void swap(size_t _i0, size_t _i1) + virtual void reserve(size_t _n) override { data_.reserve(_n); } + virtual void resize(size_t _n) override { data_.resize(_n); } + virtual void clear() override { data_.clear(); vector_type().swap(data_); } + virtual void push_back() override { data_.push_back(T()); } + virtual void swap(size_t _i0, size_t _i1) override { std::swap(data_[_i0], data_[_i1]); } - virtual void copy(size_t _i0, size_t _i1) + virtual void copy(size_t _i0, size_t _i1) override { data_[_i1] = data_[_i0]; } public: - virtual void set_persistent( bool _yn ) + virtual void set_persistent( bool _yn ) override { check_and_set_persistent( _yn ); } - virtual size_t n_elements() const { return data_.size(); } - virtual size_t element_size() const { return IO::size_of(); } + virtual size_t n_elements() const override { return data_.size(); } + virtual size_t element_size() const override { return IO::size_of(); } #ifndef DOXY_IGNORE_THIS struct plus { @@ -138,17 +135,17 @@ public: }; #endif - virtual size_t size_of(void) const + virtual size_t size_of(void) const override { if (element_size() != IO::UnknownSize) return this->BaseProperty::size_of(n_elements()); return std::accumulate(data_.begin(), data_.end(), size_t(0), plus()); } - virtual size_t size_of(size_t _n_elem) const + virtual size_t size_of(size_t _n_elem) const override { return this->BaseProperty::size_of(_n_elem); } - virtual size_t store( std::ostream& _ostr, bool _swap ) const + virtual size_t store( std::ostream& _ostr, bool _swap ) const override { if ( IO::is_streamable() ) return IO::store(_ostr, data_, _swap ); @@ -158,7 +155,7 @@ public: return bytes; } - virtual size_t restore( std::istream& _istr, bool _swap ) + virtual size_t restore( std::istream& _istr, bool _swap ) override { if ( IO::is_streamable() ) return IO::restore(_istr, data_, _swap ); @@ -178,17 +175,17 @@ public: // data access interface return &data_[0]; } - - /// Get reference to property vector (be careful, improper usage, e.g. resizing, may crash OpenMesh!!!) - vector_type& data_vector() { - return data_; - } - - /// Const access to property vector - const vector_type& data_vector() const { - return data_; - } - + + /// Get reference to property vector (be careful, improper usage, e.g. resizing, may crash OpenMesh!!!) + vector_type& data_vector() { + return data_; + } + + /// Const access to property vector + const vector_type& data_vector() const { + return data_; + } + /// Access the i'th element. No range check is performed! reference operator[](int _idx) { @@ -204,7 +201,7 @@ public: // data access interface } /// Make a copy of self. - PropertyT* clone() const + PropertyT* clone() const override { PropertyT* p = new PropertyT( *this ); return p; @@ -235,37 +232,37 @@ public: public: - PropertyT(const std::string& _name = "") - : BaseProperty(_name) + explicit PropertyT(const std::string& _name = "", const std::string& _internal_type_name="" ) + : BaseProperty(_name, _internal_type_name) { } public: // inherited from BaseProperty - virtual void reserve(size_t _n) { data_.reserve(_n); } - virtual void resize(size_t _n) { data_.resize(_n); } - virtual void clear() { data_.clear(); vector_type().swap(data_); } - virtual void push_back() { data_.push_back(bool()); } - virtual void swap(size_t _i0, size_t _i1) + virtual void reserve(size_t _n) override { data_.reserve(_n); } + virtual void resize(size_t _n) override { data_.resize(_n); } + virtual void clear() override { data_.clear(); vector_type().swap(data_); } + virtual void push_back() override { data_.push_back(bool()); } + virtual void swap(size_t _i0, size_t _i1) override { bool t(data_[_i0]); data_[_i0]=data_[_i1]; data_[_i1]=t; } - virtual void copy(size_t _i0, size_t _i1) + virtual void copy(size_t _i0, size_t _i1) override { data_[_i1] = data_[_i0]; } public: - virtual void set_persistent( bool _yn ) + virtual void set_persistent( bool _yn ) override { check_and_set_persistent( _yn ); } - virtual size_t n_elements() const { return data_.size(); } - virtual size_t element_size() const { return UnknownSize; } - virtual size_t size_of() const { return size_of( n_elements() ); } - virtual size_t size_of(size_t _n_elem) const + virtual size_t n_elements() const override { return data_.size(); } + virtual size_t element_size() const override { return UnknownSize; } + virtual size_t size_of() const override { return size_of( n_elements() ); } + virtual size_t size_of(size_t _n_elem) const override { return _n_elem / 8 + ((_n_elem % 8)!=0); } - size_t store( std::ostream& _ostr, bool /* _swap */ ) const + size_t store( std::ostream& _ostr, bool /* _swap */ ) const override { size_t bytes = 0; @@ -304,7 +301,7 @@ public: return bytes; } - size_t restore( std::istream& _istr, bool /* _swap */ ) + size_t restore( std::istream& _istr, bool /* _swap */ ) override { size_t bytes = 0; @@ -342,17 +339,17 @@ public: public: - - /// Get reference to property vector (be careful, improper usage, e.g. resizing, may crash OpenMesh!!!) - vector_type& data_vector() { - return data_; - } - - /// Const access to property vector - const vector_type& data_vector() const { - return data_; - } - + + /// Get reference to property vector (be careful, improper usage, e.g. resizing, may crash OpenMesh!!!) + vector_type& data_vector() { + return data_; + } + + /// Const access to property vector + const vector_type& data_vector() const { + return data_; + } + /// Access the i'th element. No range check is performed! reference operator[](int _idx) { @@ -368,7 +365,7 @@ public: } /// Make a copy of self. - PropertyT* clone() const + PropertyT* clone() const override { PropertyT* p = new PropertyT( *this ); return p; @@ -399,47 +396,47 @@ public: public: - PropertyT(const std::string& _name = "") - : BaseProperty(_name) + explicit PropertyT(const std::string& _name = "", const std::string& _internal_type_name="" ) + : BaseProperty(_name, _internal_type_name) { } public: // inherited from BaseProperty - virtual void reserve(size_t _n) { data_.reserve(_n); } - virtual void resize(size_t _n) { data_.resize(_n); } - virtual void clear() { data_.clear(); vector_type().swap(data_); } - virtual void push_back() { data_.push_back(std::string()); } - virtual void swap(size_t _i0, size_t _i1) { + virtual void reserve(size_t _n) override { data_.reserve(_n); } + virtual void resize(size_t _n) override { data_.resize(_n); } + virtual void clear() override { data_.clear(); vector_type().swap(data_); } + virtual void push_back() override { data_.push_back(std::string()); } + virtual void swap(size_t _i0, size_t _i1) override { std::swap(data_[_i0], data_[_i1]); } - virtual void copy(size_t _i0, size_t _i1) + virtual void copy(size_t _i0, size_t _i1) override { data_[_i1] = data_[_i0]; } public: - virtual void set_persistent( bool _yn ) + virtual void set_persistent( bool _yn ) override { check_and_set_persistent( _yn ); } - virtual size_t n_elements() const { return data_.size(); } - virtual size_t element_size() const { return UnknownSize; } - virtual size_t size_of() const + virtual size_t n_elements() const override { return data_.size(); } + virtual size_t element_size() const override { return UnknownSize; } + virtual size_t size_of() const override { return IO::size_of( data_ ); } - virtual size_t size_of(size_t /* _n_elem */) const + virtual size_t size_of(size_t /* _n_elem */) const override { return UnknownSize; } /// Store self as one binary block. Max. length of a string is 65535 bytes. - size_t store( std::ostream& _ostr, bool _swap ) const + size_t store( std::ostream& _ostr, bool _swap ) const override { return IO::store( _ostr, data_, _swap ); } - size_t restore( std::istream& _istr, bool _swap ) + size_t restore( std::istream& _istr, bool _swap ) override { return IO::restore( _istr, data_, _swap ); } public: const value_type* data() const { if( data_.empty() ) - return 0; + return nullptr; return (value_type*) &data_[0]; } @@ -456,7 +453,7 @@ public: return ((value_type*) &data_[0])[_idx]; } - PropertyT* clone() const { + PropertyT* clone() const override { PropertyT* p = new PropertyT( *this ); return p; } @@ -488,6 +485,7 @@ struct VPropHandleT : public BasePropHandleT { typedef T Value; typedef T value_type; + typedef VertexHandle Handle; explicit VPropHandleT(int _idx=-1) : BasePropHandleT(_idx) {} explicit VPropHandleT(const BasePropHandleT& _b) : BasePropHandleT(_b) {} @@ -502,6 +500,7 @@ struct HPropHandleT : public BasePropHandleT { typedef T Value; typedef T value_type; + typedef HalfedgeHandle Handle; explicit HPropHandleT(int _idx=-1) : BasePropHandleT(_idx) {} explicit HPropHandleT(const BasePropHandleT& _b) : BasePropHandleT(_b) {} @@ -516,6 +515,7 @@ struct EPropHandleT : public BasePropHandleT { typedef T Value; typedef T value_type; + typedef EdgeHandle Handle; explicit EPropHandleT(int _idx=-1) : BasePropHandleT(_idx) {} explicit EPropHandleT(const BasePropHandleT& _b) : BasePropHandleT(_b) {} @@ -530,6 +530,7 @@ struct FPropHandleT : public BasePropHandleT { typedef T Value; typedef T value_type; + typedef FaceHandle Handle; explicit FPropHandleT(int _idx=-1) : BasePropHandleT(_idx) {} explicit FPropHandleT(const BasePropHandleT& _b) : BasePropHandleT(_b) {} @@ -544,11 +545,39 @@ struct MPropHandleT : public BasePropHandleT { typedef T Value; typedef T value_type; + typedef MeshHandle Handle; explicit MPropHandleT(int _idx=-1) : BasePropHandleT(_idx) {} explicit MPropHandleT(const BasePropHandleT& _b) : BasePropHandleT(_b) {} }; +template +struct PropHandle; + +template <> +struct PropHandle { + template + using type = VPropHandleT; +}; + +template <> +struct PropHandle { + template + using type = HPropHandleT; +}; + +template <> +struct PropHandle { + template + using type = EPropHandleT; +}; + +template <> +struct PropHandle { + template + using type = FPropHandleT; +}; + } // namespace OpenMesh //============================================================================= #endif // OPENMESH_PROPERTY_HH defined diff --git a/src/OpenMesh/Core/Utils/PropertyContainer.hh b/src/OpenMesh/Core/Utils/PropertyContainer.hh index d8d7393d..297d16b9 100644 --- a/src/OpenMesh/Core/Utils/PropertyContainer.hh +++ b/src/OpenMesh/Core/Utils/PropertyContainer.hh @@ -39,22 +39,13 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef OPENMESH_PROPERTYCONTAINER #define OPENMESH_PROPERTYCONTAINER -// Use static casts when not debugging -#ifdef NDEBUG -#define OM_FORCE_STATIC_CAST -#endif - #include +#include //----------------------------------------------------------------------------- namespace OpenMesh @@ -107,9 +98,9 @@ public: { Properties::iterator p_it=properties_.begin(), p_end=properties_.end(); int idx=0; - for ( ; p_it!=p_end && *p_it!=NULL; ++p_it, ++idx ) {}; - if (p_it==p_end) properties_.push_back(NULL); - properties_[idx] = new PropertyT(_name); + for ( ; p_it!=p_end && *p_it!=nullptr; ++p_it, ++idx ) {}; + if (p_it==p_end) properties_.push_back(nullptr); + properties_[idx] = new PropertyT(_name, get_type_name() ); // create a new property with requested name and given (system dependent) internal typename return BasePropHandleT(idx); } @@ -120,12 +111,9 @@ public: Properties::const_iterator p_it = properties_.begin(); for (int idx=0; p_it != properties_.end(); ++p_it, ++idx) { - if (*p_it != NULL && + if (*p_it != nullptr && (*p_it)->name() == _name //skip deleted properties -// Skip type check -#ifndef OM_FORCE_STATIC_CAST - && dynamic_cast*>(properties_[idx]) != NULL //check type -#endif + && (*p_it)->internal_type_name() == get_type_name() // new check type ) { return BasePropHandleT(idx); @@ -139,39 +127,33 @@ public: Properties::const_iterator p_it = properties_.begin(); for (int idx=0; p_it != properties_.end(); ++p_it, ++idx) { - if (*p_it != NULL && (*p_it)->name() == _name) //skip deleted properties + if (*p_it != nullptr && (*p_it)->name() == _name) //skip deleted properties { return *p_it; } } - return NULL; + return nullptr; } template PropertyT& property(BasePropHandleT _h) { assert(_h.idx() >= 0 && _h.idx() < (int)properties_.size()); - assert(properties_[_h.idx()] != NULL); -#ifdef OM_FORCE_STATIC_CAST - return *static_cast *> (properties_[_h.idx()]); -#else - PropertyT* p = dynamic_cast*>(properties_[_h.idx()]); - assert(p != NULL); + assert(properties_[_h.idx()] != nullptr); + assert( properties_[_h.idx()]->internal_type_name() == get_type_name() ); + PropertyT *p = static_cast< PropertyT* > (properties_[_h.idx()]); + assert(p != nullptr); return *p; -#endif } template const PropertyT& property(BasePropHandleT _h) const { assert(_h.idx() >= 0 && _h.idx() < (int)properties_.size()); - assert(properties_[_h.idx()] != NULL); -#ifdef OM_FORCE_STATIC_CAST - return *static_cast*>(properties_[_h.idx()]); -#else - PropertyT* p = dynamic_cast*>(properties_[_h.idx()]); - assert(p != NULL); + assert(properties_[_h.idx()] != nullptr); + assert( properties_[_h.idx()]->internal_type_name() == get_type_name() ); + PropertyT *p = static_cast< PropertyT* > (properties_[_h.idx()]); + assert(p != nullptr); return *p; -#endif } @@ -179,7 +161,7 @@ public: { assert(_h.idx() >= 0 && _h.idx() < (int)properties_.size()); delete properties_[_h.idx()]; - properties_[_h.idx()] = NULL; + properties_[_h.idx()] = nullptr; } @@ -286,8 +268,8 @@ protected: // generic add/get { Properties::iterator p_it=properties_.begin(), p_end=properties_.end(); size_t idx=0; - for (; p_it!=p_end && *p_it!=NULL; ++p_it, ++idx) {}; - if (p_it==p_end) properties_.push_back(NULL); + for (; p_it!=p_end && *p_it!=nullptr; ++p_it, ++idx) {}; + if (p_it==p_end) properties_.push_back(nullptr); properties_[idx] = _bp; return idx; } @@ -295,18 +277,18 @@ protected: // generic add/get BaseProperty& _property( size_t _idx ) { assert( _idx < properties_.size()); - assert( properties_[_idx] != NULL); + assert( properties_[_idx] != nullptr); BaseProperty *p = properties_[_idx]; - assert( p != NULL ); + assert( p != nullptr ); return *p; } const BaseProperty& _property( size_t _idx ) const { assert( _idx < properties_.size()); - assert( properties_[_idx] != NULL); + assert( properties_[_idx] != nullptr); BaseProperty *p = properties_[_idx]; - assert( p != NULL ); + assert( p != nullptr ); return *p; } @@ -327,21 +309,21 @@ private: #ifndef DOXY_IGNORE_THIS struct Reserve { - Reserve(size_t _n) : n_(_n) {} + explicit Reserve(size_t _n) : n_(_n) {} void operator()(BaseProperty* _p) const { if (_p) _p->reserve(n_); } size_t n_; }; struct Resize { - Resize(size_t _n) : n_(_n) {} + explicit Resize(size_t _n) : n_(_n) {} void operator()(BaseProperty* _p) const { if (_p) _p->resize(n_); } size_t n_; }; struct ResizeIfSmaller { - ResizeIfSmaller(size_t _n) : n_(_n) {} + explicit ResizeIfSmaller(size_t _n) : n_(_n) {} void operator()(BaseProperty* _p) const { if (_p && _p->n_elements() < n_) _p->resize(n_); } size_t n_; }; @@ -362,7 +344,7 @@ private: struct Delete { Delete() {} - void operator()(BaseProperty* _p) const { if (_p) delete _p; _p=NULL; } + void operator()(BaseProperty* _p) const { if (_p) delete _p; } }; #endif diff --git a/src/OpenMesh/Core/Utils/PropertyManager.hh b/src/OpenMesh/Core/Utils/PropertyManager.hh index ae8ad189..b1726a36 100644 --- a/src/OpenMesh/Core/Utils/PropertyManager.hh +++ b/src/OpenMesh/Core/Utils/PropertyManager.hh @@ -39,16 +39,12 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ - #ifndef PROPERTYMANAGER_HH_ #define PROPERTYMANAGER_HH_ +#include +#include +#include #include #include #include @@ -60,57 +56,84 @@ namespace OpenMesh { * It also defines convenience operators to access the encapsulated * property's value. * - * For C++11, it is recommended to use the factory functions - * makePropertyManagerFromNew, makePropertyManagerFromExisting, - * makePropertyManagerFromExistingOrNew to construct a PropertyManager, e.g. + * Note that the second template parameter is depcretated. * * \code - * TriMesh mesh; - * auto visited = makePropertyManagerFromNew>(mesh, "visited.plugin-example.i8.informatik.rwth-aachen.de"); + * { + * TriMesh mesh; + * auto visited = makeTemporaryProperty(mesh); * - * for (auto vh : mesh.vertices()) { - * if (!visited[vh]) { - * visitComponent(mesh, vh, visited); + * for (auto vh : mesh.vertices()) { + * if (!visited[vh]) { + * visitComponent(mesh, vh, visited); + * } * } + * // The property is automatically removed at the end of the scope * } * \endcode - * - * For C++98, it is usually more convenient to use the constructor explicitly, - * i.e. - * - * \code - * TriMesh mesh; - * PropertyManager, TriMesh> visited(mesh, "visited.plugin-example.i8.informatik.rwth-aachen.de"); - * - * for (TriMesh::VertexIter vh_it = mesh.begin(); ... ; ...) { - * if (!visited[*vh_it]) { - * visitComponent(mesh, *vh_it, visited); - * } - * } - * \endcode - * */ -template +template class PropertyManager { -#if (defined(_MSC_VER) && (_MSC_VER >= 1800)) || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__) + public: - PropertyManager(const PropertyManager&) = delete; - PropertyManager& operator=(const PropertyManager&) = delete; -#else + using Value = typename PROPTYPE::Value; + using value_type = typename PROPTYPE::value_type; + using Handle = typename PROPTYPE::Handle; + using Self = PropertyManager; + using Reference = typename PROPTYPE::reference; + using ConstReference = typename PROPTYPE::const_reference; + private: - /** - * Noncopyable because there aren't no straightforward copy semantics. - */ - PropertyManager(const PropertyManager&); + // Mesh properties (MPropHandleT<...>) are stored differently than the other properties. + // This class implements different behavior when copying or swapping data from one + // property manager to a another one. + template + struct StorageT; - /** - * Noncopyable because there aren't no straightforward copy semantics. - */ - PropertyManager& operator=(const PropertyManager&); -#endif + // specialization for Mesh Properties + template + struct StorageT> { + static void copy(const PropertyManager& from, PropertyManager2& to) { + *to = *from; + } + static void swap(PropertyManager& from, PropertyManager2& to) { + std::swap(*to, *from); + } + static ConstReference access_property_const(PolyConnectivity& mesh, const PROPTYPE& prop_handle, const Handle&) { + return mesh.property(prop_handle); + } + static Reference access_property(PolyConnectivity& mesh, const PROPTYPE& prop_handle, const Handle&) { + return mesh.property(prop_handle); + } + }; + + // definition for other Mesh Properties + template + struct StorageT { + static void copy(const PropertyManager& from, PropertyManager2& to) { + from.copy_to(from.mesh_.template all_elements(), to, to.mesh_.template all_elements()); + } + static void swap(PropertyManager& lhs, PropertyManager2& rhs) { + std::swap(lhs.mesh().property(lhs.prop_).data_vector(), rhs.mesh().property(rhs.prop_).data_vector()); + // resize the property to the correct size + lhs.mesh().property(lhs.prop_).resize(lhs.mesh().template n_elements()); + rhs.mesh().property(rhs.prop_).resize(rhs.mesh().template n_elements()); + } + static ConstReference access_property_const(PolyConnectivity& mesh, const PROPTYPE& prop_handle, const Handle& handle) { + return mesh.property(prop_handle, handle); + } + static Reference access_property(PolyConnectivity& mesh, const PROPTYPE& prop_handle, const Handle& handle) { + return mesh.property(prop_handle, handle); + } + }; + + using Storage = StorageT; public: + /** + * @deprecated Use a constructor without \p existing and check existance with hasProperty() instead. + * * Constructor. * * Throws an \p std::runtime_error if \p existing is true and @@ -124,22 +147,128 @@ class PropertyManager { * the instance merely acts as a convenience wrapper around an existing property with no * lifecycle management whatsoever. * - * @see PropertyManager::createIfNotExists, makePropertyManagerFromNew, - * makePropertyManagerFromExisting, makePropertyManagerFromExistingOrNew + * @see PropertyManager::getOrMakeProperty, PropertyManager::getProperty, + * PropertyManager::makeTemporaryProperty */ - PropertyManager(MeshT &mesh, const char *propname, bool existing = false) : mesh_(&mesh), retain_(existing), name_(propname) { + OM_DEPRECATED("Use the constructor without parameter 'existing' instead. Check for existance with hasProperty") // As long as this overload exists, initial value must be first parameter due to ambiguity for properties of type bool + PropertyManager(PolyConnectivity& mesh, const char *propname, bool existing) : mesh_(mesh), retain_(existing), name_(propname) { if (existing) { - if (!mesh_->get_property_handle(prop_, propname)) { + if (!PropertyManager::mesh().get_property_handle(prop_, propname)) { std::ostringstream oss; oss << "Requested property handle \"" << propname << "\" does not exist."; throw std::runtime_error(oss.str()); } } else { - mesh_->add_property(prop_, propname); + PropertyManager::mesh().add_property(prop_, propname); } } - PropertyManager() : mesh_(0), retain_(false) { + /** + * Constructor. + * + * Asks for a property with name propname and creates one if none exists. Lifetime is not managed. + * + * @param mesh The mesh on which to create the property. + * @param propname The name of the property. + */ + PropertyManager(PolyConnectivity& mesh, const char *propname) : mesh_(mesh), retain_(true), name_(propname) { + if (!PropertyManager::mesh().get_property_handle(prop_, propname)) { + PropertyManager::mesh().add_property(prop_, propname); + } + } + + /** + * Constructor. + * + * Asks for a property with name propname and creates one if none exists. Lifetime is not managed. + * + * @param initial_value If the proeprty is newly created, it will be initialized with initial_value. + * If the property already existed, nothing is changes. + * @param mesh The mesh on which to create the property. + * @param propname The name of the property. + */ + PropertyManager(const Value& initial_value, PolyConnectivity& mesh, const char *propname) : mesh_(mesh), retain_(true), name_(propname) { + if (!mesh_.get_property_handle(prop_, propname)) { + PropertyManager::mesh().add_property(prop_, propname); + set_range(mesh_.all_elements(), initial_value); + } + } + + /** + * Constructor. + * + * Create an anonymous property. Lifetime is managed. + * + * @param mesh The mesh on which to create the property. + */ + PropertyManager(const PolyConnectivity& mesh) : mesh_(mesh), retain_(false), name_("") { + PropertyManager::mesh().add_property(prop_, name_); + } + + /** + * Constructor. + * + * Create an anonymous property. Lifetime is managed. + * + * @param initial_value The property will be initialized with initial_value. + * @param mesh The mesh on which to create the property. + */ + PropertyManager(const Value& initial_value, const PolyConnectivity& mesh) : mesh_(mesh), retain_(false), name_("") { + PropertyManager::mesh().add_property(prop_, name_); + set_range(mesh_.all_elements(), initial_value); + } + + /** + * Constructor. + * + * Create a wrapper around an existing property. Lifetime is not managed. + * + * @param mesh The mesh on which to create the property. + * @param property_handle Handle to an existing property that should be wrapped. + */ + PropertyManager(PolyConnectivity& mesh, PROPTYPE property_handle) : mesh_(mesh), prop_(property_handle), retain_(true), name_() { + } + + PropertyManager() = delete; + + PropertyManager(const PropertyManager& rhs) + : + mesh_(rhs.mesh_), + prop_(), + retain_(rhs.retain_), + name_(rhs.name_) + { + if (rhs.retain_) // named property -> create a property manager referring to the same + { + prop_ = rhs.prop_; + } + else // unnamed property -> create a property manager refering to a new property and copy the contents + { + PropertyManager::mesh().add_property(prop_, name_); + Storage::copy(rhs, *this); + } + } + + + /** + * Create property manager referring to a copy of the current property. + * This can be used to explicitely create a copy of a named property. The cloned property + * will be unnamed. + */ + PropertyManager clone() + { + PropertyManager result(this->mesh()); + Storage::copy(*this, result); + return result; + } + + PropertyManager& operator=(const PropertyManager& rhs) + { + if (&mesh_ == &rhs.mesh_ && prop_ == rhs.prop_) + ; // nothing to do + else + Storage::copy(rhs, *this); + return *this; } ~PropertyManager() { @@ -147,49 +276,84 @@ class PropertyManager { } void swap(PropertyManager &rhs) { - std::swap(mesh_, rhs.mesh_); - std::swap(prop_, rhs.prop_); - std::swap(retain_, rhs.retain_); - std::swap(name_, rhs.name_); + // swap the data stored in the properties + Storage::swap(rhs, *this); } - static bool propertyExists(MeshT &mesh, const char *propname) { + static bool propertyExists(PolyConnectivity &mesh, const char *propname) { PROPTYPE dummy; return mesh.get_property_handle(dummy, propname); } - bool isValid() const { return mesh_ != 0; } + bool isValid() const { return prop_.is_valid(); } operator bool() const { return isValid(); } const PROPTYPE &getRawProperty() const { return prop_; } const std::string &getName() const { return name_; } - MeshT &getMesh() const { return *mesh_; } + /** + * Get the mesh corresponding to the property. + * + * If you use PropertyManager without second template parameter (recommended) + * you need to specify the actual mesh type when using this function, e.g.: + * \code + * { + * TriMesh mesh; + * auto visited = VProp(mesh); + * TriMesh& mesh_ref = visited.getMesh(); + * } + * + */ + template + const MeshType& getMesh() const { return dynamic_cast(mesh_); } -#if (defined(_MSC_VER) && (_MSC_VER >= 1800)) || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__) - /// Only for pre C++11 compatibility. + const MeshT& getMesh() const { return dynamic_cast(mesh_); } - typedef PropertyManager Proxy; + + /** + * @deprecated This method no longer has any effect. Instead, named properties are always retained, while unnamed ones are not + * + * Tells the PropertyManager whether lifetime should be managed or not. + */ + OM_DEPRECATED("retain no longer has any effect. Instead, named properties are always retained, while unnamed ones are not.") + void retain(bool = true) {} /** * Move constructor. Transfers ownership (delete responsibility). */ - PropertyManager(PropertyManager &&rhs) : mesh_(rhs.mesh_), prop_(rhs.prop_), retain_(rhs.retain_), name_(rhs.name_) { - rhs.retain_ = true; + PropertyManager(PropertyManager &&rhs) + : + mesh_(rhs.mesh_), + prop_(rhs.prop_), + retain_(rhs.retain_), + name_(rhs.name_) + { + if (!rhs.retain_) + rhs.prop_.invalidate(); // only invalidate unnamed properties } /** * Move assignment. Transfers ownership (delete responsibility). */ - PropertyManager &operator=(PropertyManager &&rhs) { - if (&rhs != this) { - deleteProperty(); - mesh_ = rhs.mesh_; - prop_ = rhs.prop_; - retain_ = rhs.retain_; - name_ = rhs.name_; - rhs.retain_ = true; + PropertyManager& operator=(PropertyManager&& rhs) + { + if ((&mesh_ != &rhs.mesh_) || (prop_ != rhs.prop_)) + { + if (rhs.retain_) + { + // retained properties cannot be invalidated. Copy instead + Storage::copy(rhs, *this); + } + else + { + // swap the data stored in the properties + Storage::swap(rhs, *this); + // remove the property from rhs + rhs.mesh().remove_property(rhs.prop_); + // invalidate prop_ + rhs.prop_.invalidate(); + } } return *this; } @@ -201,11 +365,8 @@ class PropertyManager { * * @see makePropertyManagerFromExistingOrNew */ - static PropertyManager createIfNotExists(MeshT &mesh, const char *propname) { - PROPTYPE dummy_prop; - PropertyManager pm(mesh, propname, mesh.get_property_handle(dummy_prop, propname)); - pm.retain(); - return std::move(pm); + static PropertyManager createIfNotExists(PolyConnectivity &mesh, const char *propname) { + return PropertyManager(mesh, propname); } /** @@ -218,7 +379,7 @@ class PropertyManager { * @see makePropertyManagerFromExistingOrNew */ template - static PropertyManager createIfNotExists(MeshT &mesh, const char *propname, + static PropertyManager createIfNotExists(PolyConnectivity &mesh, const char *propname, const ITERATOR_TYPE &begin, const ITERATOR_TYPE &end, const PROP_VALUE &init_value) { const bool exists = propertyExists(mesh, propname); @@ -239,120 +400,43 @@ class PropertyManager { * @see makePropertyManagerFromExistingOrNew */ template - static PropertyManager createIfNotExists(MeshT &mesh, const char *propname, + static PropertyManager createIfNotExists(PolyConnectivity &mesh, const char *propname, const ITERATOR_RANGE &range, const PROP_VALUE &init_value) { return createIfNotExists( mesh, propname, range.begin(), range.end(), init_value); } - PropertyManager duplicate(const char *clone_name) { - PropertyManager pm(*mesh_, clone_name, false); - pm.mesh_->property(pm.prop_) = mesh_->property(prop_); - return pm; - } /** - * Included for backwards compatibility with non-C++11 version. - */ - PropertyManager move() { - return std::move(*this); - } - -#else - class Proxy { - private: - Proxy(MeshT *mesh_, PROPTYPE prop_, bool retain_, const std::string &name_) : - mesh_(mesh_), prop_(prop_), retain_(retain_), name_(name_) {} - MeshT *mesh_; - PROPTYPE prop_; - bool retain_; - std::string name_; - - friend class PropertyManager; - }; - - operator Proxy() { - Proxy p(mesh_, prop_, retain_, name_); - mesh_ = 0; - retain_ = true; - return p; - } - - Proxy move() { - return (Proxy)*this; - } - - PropertyManager(Proxy p) : mesh_(p.mesh_), prop_(p.prop_), retain_(p.retain_), name_(p.name_) {} - - PropertyManager &operator=(Proxy p) { - PropertyManager(p).swap(*this); - return *this; - } - - /** - * Create a property manager for the supplied property and mesh. - * If the property doesn't exist, it is created. In any case, - * lifecycle management is disabled. + * Access the value of the encapsulated mesh property. * - * @see makePropertyManagerFromExistingOrNew - */ - static Proxy createIfNotExists(MeshT &mesh, const char *propname) { - PROPTYPE dummy_prop; - PropertyManager pm(mesh, propname, mesh.get_property_handle(dummy_prop, propname)); - pm.retain(); - return (Proxy)pm; - } - - /** - * Like createIfNotExists() with two parameters except, if the property - * doesn't exist, it is initialized with the supplied value over - * the supplied range after creation. If the property already exists, - * this method has the exact same effect as the two parameter version. - * Lifecycle management is disabled in any case. + * Example: + * @code + * PolyMesh m; + * auto description = getOrMakeProperty(m, "description"); + * *description = "This is a very nice mesh."; + * @endcode * - * @see makePropertyManagerFromExistingOrNew + * @note This method is only used for mesh properties. */ - template - static Proxy createIfNotExists(MeshT &mesh, const char *propname, - const ITERATOR_TYPE &begin, const ITERATOR_TYPE &end, - const PROP_VALUE &init_value) { - const bool exists = propertyExists(mesh, propname); - PropertyManager pm(mesh, propname, exists); - pm.retain(); - if (!exists) - pm.set_range(begin, end, init_value); - return (Proxy)pm; + typename PROPTYPE::reference& operator*() { + return mesh().mproperty(prop_)[0]; } - Proxy duplicate(const char *clone_name) { - PropertyManager pm(*mesh_, clone_name, false); - pm.mesh_->property(pm.prop_) = mesh_->property(prop_); - return (Proxy)pm; - } -#endif - /** - * \brief Disable lifecycle management for this property. + * Access the value of the encapsulated mesh property. * - * If this method is called, the encapsulated property will not be deleted - * upon destruction of the PropertyManager instance. + * Example: + * @code + * PolyMesh m; + * auto description = getProperty(m, "description"); + * std::cout << *description << std::endl; + * @endcode + * + * @note This method is only used for mesh properties. */ - inline void retain(bool doRetain = true) { - retain_ = doRetain; - } - - /** - * Access the encapsulated property. - */ - inline PROPTYPE &operator* () { - return prop_; - } - - /** - * Access the encapsulated property. - */ - inline const PROPTYPE &operator* () const { - return prop_; + typename PROPTYPE::const_reference& operator*() const { + return mesh().mproperty(prop_)[0]; } /** @@ -362,9 +446,8 @@ class PropertyManager { * * @param handle A handle of the appropriate handle type. (I.e. \p VertexHandle for \p VPropHandleT, etc.) */ - template - inline typename PROPTYPE::reference operator[] (const HandleType &handle) { - return mesh_->property(prop_, handle); + inline typename PROPTYPE::reference operator[] (Handle handle) { + return mesh().property(prop_, handle); } /** @@ -374,9 +457,32 @@ class PropertyManager { * * @param handle A handle of the appropriate handle type. (I.e. \p VertexHandle for \p VPropHandleT, etc.) */ - template - inline typename PROPTYPE::const_reference operator[] (const HandleType &handle) const { - return mesh_->property(prop_, handle); + inline typename PROPTYPE::const_reference operator[] (const Handle& handle) const { + return mesh().property(prop_, handle); + } + + /** + * Enables convenient access to the encapsulated property. + * + * For a usage example see this class' documentation. + * + * @param handle A handle of the appropriate handle type. (I.e. \p VertexHandle for \p VPropHandleT, etc.) + */ + inline typename PROPTYPE::reference operator() (const Handle& handle = Handle()) { +// return mesh().property(prop_, handle); + return Storage::access_property(mesh(), prop_, handle); + } + + /** + * Enables convenient access to the encapsulated property. + * + * For a usage example see this class' documentation. + * + * @param handle A handle of the appropriate handle type. (I.e. \p VertexHandle for \p VPropHandleT, etc.) + */ + inline typename PROPTYPE::const_reference operator() (const Handle& handle = Handle()) const { +// return mesh().property(prop_, handle); + return Storage::access_property_const(mesh(), prop_, handle); } /** @@ -385,7 +491,7 @@ class PropertyManager { * Examples: * \code * MeshT mesh; - * PropertyManager, MeshT> distance( + * PropertyManager> distance( * mesh, "distance.plugin-example.i8.informatik.rwth-aachen.de"); * distance.set_range( * mesh.vertices_begin(), mesh.vertices_end(), @@ -433,9 +539,9 @@ class PropertyManager { * Will be used with dst_propmanager. Used to double check the bounds. */ template + typename HandleTypeIterator_2> void copy_to(HandleTypeIterator begin, HandleTypeIterator end, - PropertyManager &dst_propmanager, + PropertyManager &dst_propmanager, HandleTypeIterator_2 dst_begin, HandleTypeIterator_2 dst_end) const { for (; begin != end && dst_begin != dst_end; ++begin, ++dst_begin) { @@ -444,14 +550,15 @@ class PropertyManager { } template + typename RangeType_2> void copy_to(const RangeType &range, - PropertyManager &dst_propmanager, + PropertyManager &dst_propmanager, const RangeType_2 &dst_range) const { copy_to(range.begin(), range.end(), dst_propmanager, dst_range.begin(), dst_range.end()); } + /** * Copy the values of a property from a source range to * a target range. The source range must not be smaller than the @@ -466,15 +573,15 @@ class PropertyManager { * @param dst_mesh Destination mesh on which to copy. * @param dst_range Destination range. */ - template + template static void copy(const char *prop_name, - MeshT &src_mesh, const RangeType &src_range, - MeshT_2 &dst_mesh, const RangeType_2 &dst_range) { + PolyConnectivity &src_mesh, const RangeType &src_range, + PolyConnectivity &dst_mesh, const RangeType_2 &dst_range) { - typedef OpenMesh::PropertyManager DstPM; + typedef OpenMesh::PropertyManager DstPM; DstPM dst(DstPM::createIfNotExists(dst_mesh, prop_name)); - typedef OpenMesh::PropertyManager SrcPM; + typedef OpenMesh::PropertyManager SrcPM; SrcPM src(src_mesh, prop_name, true); src.copy_to(src_range, dst, dst_range); @@ -482,30 +589,237 @@ class PropertyManager { private: void deleteProperty() { - if (!retain_) - mesh_->remove_property(prop_); + if (!retain_ && prop_.is_valid()) + mesh().remove_property(prop_); + } + + PolyConnectivity& mesh() const + { + return const_cast(mesh_); } private: - MeshT *mesh_; + const PolyConnectivity& mesh_; PROPTYPE prop_; bool retain_; std::string name_; }; -/** \relates PropertyManager +template +class ConstPropertyViewer +{ +public: + using Value = typename PropertyT::Value; + using value_type = typename PropertyT::value_type; + using Handle = typename PropertyT::Handle; + + ConstPropertyViewer(const PolyConnectivity& mesh, PropertyT property_handle) + : + mesh_(mesh), + prop_(property_handle) + {} + + inline const typename PropertyT::const_reference operator() (const Handle& handle) + { + return mesh_.property(prop_, handle); + } + + inline const typename PropertyT::const_reference operator[] (const Handle& handle) + { + return mesh_.property(prop_, handle); + } + +private: + const PolyConnectivity& mesh_; + PropertyT prop_; +}; + +/** @relates PropertyManager + * + * @deprecated Temporary properties should not have a name. + * + * Creates a new property whose lifetime is limited to the current scope. + * + * Used for temporary properties. Shadows any existing properties of + * matching name and type. + * + * Example: + * @code + * PolyMesh m; + * { + * auto is_quad = makeTemporaryProperty(m); + * for (auto& fh : m.faces()) { + * is_quad[fh] = (m.valence(fh) == 4); + * } + * // The property is automatically removed from the mesh at the end of the scope. + * } + * @endcode + * + * @param mesh The mesh on which the property is created + * @param propname (optional) The name of the created property + * @tparam ElementT Element type of the created property, e.g. VertexHandle, HalfedgeHandle, etc. + * @tparam T Value type of the created property, e.g., \p double, \p int, etc. + * @returns A PropertyManager handling the lifecycle of the property + */ +template +PropertyManager::type> +OM_DEPRECATED("Named temporary properties are deprecated. Either create a temporary without name or a non-temporary with name") +makeTemporaryProperty(PolyConnectivity &mesh, const char *propname) { + return PropertyManager::type>(mesh, propname, false); +} + +/** @relates PropertyManager + * + * Creates a new property whose lifetime is limited to the current scope. + * + * Used for temporary properties. Shadows any existing properties of + * matching name and type. + * + * Example: + * @code + * PolyMesh m; + * { + * auto is_quad = makeTemporaryProperty(m); + * for (auto& fh : m.faces()) { + * is_quad[fh] = (m.valence(fh) == 4); + * } + * // The property is automatically removed from the mesh at the end of the scope. + * } + * @endcode + * + * @param mesh The mesh on which the property is created + * @tparam ElementT Element type of the created property, e.g. VertexHandle, HalfedgeHandle, etc. + * @tparam T Value type of the created property, e.g., \p double, \p int, etc. + * @returns A PropertyManager handling the lifecycle of the property + */ +template +PropertyManager::type> +makeTemporaryProperty(PolyConnectivity &mesh) { + return PropertyManager::type>(mesh); +} + + +/** @relates PropertyManager + * + * Tests whether a property with the given element type, value type, and name is + * present on the given mesh. + * + * * Example: + * @code + * PolyMesh m; + * if (hasProperty(m, "is_quad")) { + * // We now know the property exists: getProperty won't throw. + * auto is_quad = getProperty(m, "is_quad"); + * // Use is_quad here. + * } + * @endcode + * + * @param mesh The mesh in question + * @param propname The property name of the expected property + * @tparam ElementT Element type of the expected property, e.g. VertexHandle, HalfedgeHandle, etc. + * @tparam T Value type of the expected property, e.g., \p double, \p int, etc. + * @tparam MeshT Type of the mesh. Can often be inferred from \p mesh + */ +template +bool +hasProperty(const PolyConnectivity &mesh, const char *propname) { + typename HandleToPropHandle::type ph; + return mesh.get_property_handle(ph, propname); +} + +/** @relates PropertyManager + * + * Obtains a handle to a named property. + * + * Example: + * @code + * PolyMesh m; + * { + * try { + * auto is_quad = getProperty(m, "is_quad"); + * // Use is_quad here. + * } + * catch (const std::runtime_error& e) { + * // There is no is_quad face property on the mesh. + * } + * } + * @endcode + * + * @pre Property with the name \p propname of matching type exists. + * @throws std::runtime_error if no property with the name \p propname of + * matching type exists. + * @param mesh The mesh on which the property is created + * @param propname The name of the created property + * @tparam ElementT Element type of the created property, e.g. VertexHandle, HalfedgeHandle, etc. + * @tparam T Value type of the created property, e.g., \p double, \p int, etc. + * @returns A PropertyManager wrapping the property + */ +template +PropertyManager::type> +getProperty(PolyConnectivity &mesh, const char *propname) { + if (!hasProperty(mesh, propname)) + { + std::ostringstream oss; + oss << "Requested property handle \"" << propname << "\" does not exist."; + throw std::runtime_error(oss.str()); + } + return PropertyManager::type>(mesh, propname); +} + +/** @relates PropertyManager + * + * Obtains a handle to a named property if it exists or creates a new one otherwise. + * + * Used for creating or accessing permanent properties. + * + * Example: + * @code + * PolyMesh m; + * { + * auto is_quad = getOrMakeProperty(m, "is_quad"); + * for (auto& fh : m.faces()) { + * is_quad[fh] = (m.valence(fh) == 4); + * } + * // The property remains on the mesh after the end of the scope. + * } + * { + * // Retrieve the property from the previous scope. + * auto is_quad = getOrMakeProperty(m, "is_quad"); + * // Use is_quad here. + * } + * @endcode + * + * @param mesh The mesh on which the property is created + * @param propname The name of the created property + * @tparam ElementT Element type of the created property, e.g. VertexHandle, HalfedgeHandle, etc. + * @tparam T Value type of the created property, e.g., \p double, \p int, etc. + * @returns A PropertyManager wrapping the property + */ +template +PropertyManager::type> +getOrMakeProperty(PolyConnectivity &mesh, const char *propname) { + return PropertyManager::type>::createIfNotExists(mesh, propname); +} + +/** @relates PropertyManager + * @deprecated Use makeTemporaryProperty() instead. + * * Creates a new property whose lifecycle is managed by the returned * PropertyManager. * - * Intended for temporary properties. Shadows any existsing properties of + * Intended for temporary properties. Shadows any existing properties of * matching name and type. */ -template -PropertyManager makePropertyManagerFromNew(MeshT &mesh, const char *propname) { - return PropertyManager(mesh, propname, false); +template +OM_DEPRECATED("Use makeTemporaryProperty instead.") +PropertyManager makePropertyManagerFromNew(PolyConnectivity &mesh, const char *propname) +{ + return PropertyManager(mesh, propname, false); } /** \relates PropertyManager + * @deprecated Use getProperty() instead. + * * Creates a non-owning wrapper for an existing mesh property (no lifecycle * management). * @@ -515,23 +829,29 @@ PropertyManager makePropertyManagerFromNew(MeshT &mesh, const c * @throws std::runtime_error if no property with the name \p propname of * matching type exists. */ -template -PropertyManager makePropertyManagerFromExisting(MeshT &mesh, const char *propname) { +template +OM_DEPRECATED("Use getProperty instead.") +PropertyManager makePropertyManagerFromExisting(PolyConnectivity &mesh, const char *propname) +{ return PropertyManager(mesh, propname, true); } -/** \relates PropertyManager +/** @relates PropertyManager + * @deprecated Use getOrMakeProperty() instead. + * * Creates a non-owning wrapper for a mesh property (no lifecycle management). * If the given property does not exist, it is created. * * Intended for creating or accessing persistent properties. */ -template -PropertyManager makePropertyManagerFromExistingOrNew(MeshT &mesh, const char *propname) { +template +OM_DEPRECATED("Use getOrMakeProperty instead.") +PropertyManager makePropertyManagerFromExistingOrNew(PolyConnectivity &mesh, const char *propname) +{ return PropertyManager::createIfNotExists(mesh, propname); } -/** \relates PropertyManager +/** @relates PropertyManager * Like the two parameter version of makePropertyManagerFromExistingOrNew() * except it initializes the property with the specified value over the * specified range if it needs to be created. If the property already exists, @@ -542,17 +862,18 @@ PropertyManager makePropertyManagerFromExistingOrNew(MeshT &mes * * Intended for creating or accessing persistent properties. */ -template -PropertyManager makePropertyManagerFromExistingOrNew( - MeshT &mesh, const char *propname, +OM_DEPRECATED("Use getOrMakeProperty instead.") +PropertyManager makePropertyManagerFromExistingOrNew( + PolyConnectivity &mesh, const char *propname, const ITERATOR_TYPE &begin, const ITERATOR_TYPE &end, const PROP_VALUE &init_value) { - return PropertyManager::createIfNotExists( + return PropertyManager::createIfNotExists( mesh, propname, begin, end, init_value); } -/** \relates PropertyManager +/** @relates PropertyManager * Like the two parameter version of makePropertyManagerFromExistingOrNew() * except it initializes the property with the specified value over the * specified range if it needs to be created. If the property already exists, @@ -563,15 +884,55 @@ PropertyManager makePropertyManagerFromExistingOrNew( * * Intended for creating or accessing persistent properties. */ -template -PropertyManager makePropertyManagerFromExistingOrNew( - MeshT &mesh, const char *propname, +OM_DEPRECATED("Use getOrMakeProperty instead.") +PropertyManager makePropertyManagerFromExistingOrNew( + PolyConnectivity &mesh, const char *propname, const ITERATOR_RANGE &range, const PROP_VALUE &init_value) { - return makePropertyManagerFromExistingOrNew( + return makePropertyManagerFromExistingOrNew( mesh, propname, range.begin(), range.end(), init_value); } + +/** @relates PropertyManager + * Returns a convenience wrapper around the points property of a mesh. + */ +template +PropertyManager> +getPointsProperty(MeshT &mesh) { + return PropertyManager>(mesh, mesh.points_property_handle()); +} + +/** @relates PropertyManager + * Returns a convenience wrapper around the points property of a mesh that only allows const access. + */ +template +ConstPropertyViewer> +getPointsProperty(const MeshT &mesh) { + using PropType = OpenMesh::VPropHandleT; + return ConstPropertyViewer(mesh, mesh.points_property_handle()); +} + +template +using Prop = PropertyManager::template type>; + +template +using VProp = PropertyManager>; + +template +using HProp = PropertyManager>; + +template +using EProp = PropertyManager>; + +template +using FProp = PropertyManager>; + +template +using MProp = PropertyManager>; + + } /* namespace OpenMesh */ #endif /* PROPERTYMANAGER_HH_ */ diff --git a/src/OpenMesh/Core/Utils/RandomNumberGenerator.cc b/src/OpenMesh/Core/Utils/RandomNumberGenerator.cc index 83222b61..9d876392 100644 --- a/src/OpenMesh/Core/Utils/RandomNumberGenerator.cc +++ b/src/OpenMesh/Core/Utils/RandomNumberGenerator.cc @@ -39,14 +39,6 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision: 362 $ * - * $Date: 2011-01-26 10:21:12 +0100 (Mi, 26 Jan 2011) $ * - * * -\*===========================================================================*/ - - //============================================================================= // // Helper Functions for generating a random number between 0.0 and 1.0 with diff --git a/src/OpenMesh/Core/Utils/RandomNumberGenerator.hh b/src/OpenMesh/Core/Utils/RandomNumberGenerator.hh index aaedfcdf..c0b2be3d 100644 --- a/src/OpenMesh/Core/Utils/RandomNumberGenerator.hh +++ b/src/OpenMesh/Core/Utils/RandomNumberGenerator.hh @@ -39,18 +39,10 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision: 693 $ * - * $Date: 2012-09-23 16:25:16 +0200 (So, 23 Sep 2012) $ * - * * -\*===========================================================================*/ - - //============================================================================= // // Helper Functions for generating a random number between 0.0 and 1.0 with -// a garantueed resolution +// a guaranteed resolution // //============================================================================= diff --git a/src/OpenMesh/Core/Utils/SingletonT.hh b/src/OpenMesh/Core/Utils/SingletonT.hh index b0745c40..438cd655 100644 --- a/src/OpenMesh/Core/Utils/SingletonT.hh +++ b/src/OpenMesh/Core/Utils/SingletonT.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= @@ -53,10 +48,7 @@ // //============================================================================= - -#ifndef __SINGLETON_HH__ -#define __SINGLETON_HH__ - +#pragma once //=== INCLUDES ================================================================ @@ -147,8 +139,6 @@ private: //============================================================================= #if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_SINGLETON_C) # define OPENMESH_SINGLETON_TEMPLATES -# include "SingletonT.cc" +# include "SingletonT_impl.hh" #endif //============================================================================= -#endif // __SINGLETON_HH__ -//============================================================================= diff --git a/src/OpenMesh/Core/Utils/SingletonT.cc b/src/OpenMesh/Core/Utils/SingletonT_impl.hh similarity index 90% rename from src/OpenMesh/Core/Utils/SingletonT.cc rename to src/OpenMesh/Core/Utils/SingletonT_impl.hh index abc189ad..6ad23d66 100644 --- a/src/OpenMesh/Core/Utils/SingletonT.cc +++ b/src/OpenMesh/Core/Utils/SingletonT_impl.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= diff --git a/src/OpenMesh/Core/Utils/color_cast.hh b/src/OpenMesh/Core/Utils/color_cast.hh index 0dd9901c..8ed6f5a2 100644 --- a/src/OpenMesh/Core/Utils/color_cast.hh +++ b/src/OpenMesh/Core/Utils/color_cast.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= diff --git a/src/OpenMesh/Core/Utils/typename.hh b/src/OpenMesh/Core/Utils/typename.hh new file mode 100644 index 00000000..f67ae18b --- /dev/null +++ b/src/OpenMesh/Core/Utils/typename.hh @@ -0,0 +1,26 @@ +#pragma once + +/// Get an internal name for a type +/// Important, this is depends on compilers and versions, do NOT use in file formats! +/// This provides property type safety when only limited RTTI is available +/// Solution adapted from OpenVolumeMesh + +#include +#include + +namespace OpenMesh { + +template +std::string get_type_name() +{ +#ifdef _MSC_VER + // MSVC'S type_name returns only a friendly name with name() method, + // to get a unique name use raw_name() method instead + return typeid(T).raw_name(); +#else + // GCC and clang curently return mangled name as name(), there is no raw_name() method + return typeid(T).name(); +#endif +} + +} diff --git a/src/OpenMesh/Core/Utils/vector_cast.hh b/src/OpenMesh/Core/Utils/vector_cast.hh index 94f991a5..07e0794b 100644 --- a/src/OpenMesh/Core/Utils/vector_cast.hh +++ b/src/OpenMesh/Core/Utils/vector_cast.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= @@ -95,7 +90,6 @@ inline void vector_cast( const src_t & /*_src*/, dst_t & /*_dst*/, GenProg::Int2 { } - template inline void vector_copy( const src_t &_src, dst_t &_dst, GenProg::Int2Type ) { diff --git a/src/OpenMesh/Core/Utils/vector_traits.hh b/src/OpenMesh/Core/Utils/vector_traits.hh index fb78b3c5..801eb5c4 100644 --- a/src/OpenMesh/Core/Utils/vector_traits.hh +++ b/src/OpenMesh/Core/Utils/vector_traits.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= diff --git a/src/OpenMesh/Core/VS2008Core.vcproj b/src/OpenMesh/Core/VS2008Core.vcproj deleted file mode 100644 index 77963cf6..00000000 --- a/src/OpenMesh/Core/VS2008Core.vcproj +++ /dev/null @@ -1,578 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/OpenMesh/Examples/Examples.pro b/src/OpenMesh/Examples/Examples.pro deleted file mode 100644 index 556c16f6..00000000 --- a/src/OpenMesh/Examples/Examples.pro +++ /dev/null @@ -1,12 +0,0 @@ -Subdirs() - -addSubdirs( Tutorial01 ) -addSubdirs( Tutorial02 ) -addSubdirs( Tutorial03 ) -addSubdirs( Tutorial04 ) -addSubdirs( Tutorial05 ) -addSubdirs( Tutorial06 ) -addSubdirs( Tutorial07 ) -addSubdirs( Tutorial08 ) -addSubdirs( Tutorial09 ) -addSubdirs( Tutorial10 ) diff --git a/src/OpenMesh/Examples/Tutorial01/Tutorial01.pro b/src/OpenMesh/Examples/Tutorial01/Tutorial01.pro deleted file mode 100644 index 5d626522..00000000 --- a/src/OpenMesh/Examples/Tutorial01/Tutorial01.pro +++ /dev/null @@ -1,19 +0,0 @@ -################################################################################ -# -################################################################################ - -include( $$TOPDIR/qmake/all.include ) - -INCLUDEPATH += ../../.. - -Application() -openmesh() - -DIRECTORIES = . - -# Input -HEADERS += $$getFilesFromDir($$DIRECTORIES,*.hh) -SOURCES += $$getFilesFromDir($$DIRECTORIES,*.cc) -FORMS += $$getFilesFromDir($$DIRECTORIES,*.ui) - -################################################################################ diff --git a/src/OpenMesh/Examples/Tutorial01/cube.cc b/src/OpenMesh/Examples/Tutorial01/cube.cc index 49b309eb..33f22ae5 100644 --- a/src/OpenMesh/Examples/Tutorial01/cube.cc +++ b/src/OpenMesh/Examples/Tutorial01/cube.cc @@ -39,14 +39,6 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision: 1258 $ * - * $Date: 2015-04-28 15:07:46 +0200 (Di, 28 Apr 2015) $ * - * * - \*===========================================================================*/ - - #include // -------------------- OpenMesh #include diff --git a/src/OpenMesh/Examples/Tutorial02/Tutorial02.pro b/src/OpenMesh/Examples/Tutorial02/Tutorial02.pro deleted file mode 100644 index 5d626522..00000000 --- a/src/OpenMesh/Examples/Tutorial02/Tutorial02.pro +++ /dev/null @@ -1,19 +0,0 @@ -################################################################################ -# -################################################################################ - -include( $$TOPDIR/qmake/all.include ) - -INCLUDEPATH += ../../.. - -Application() -openmesh() - -DIRECTORIES = . - -# Input -HEADERS += $$getFilesFromDir($$DIRECTORIES,*.hh) -SOURCES += $$getFilesFromDir($$DIRECTORIES,*.cc) -FORMS += $$getFilesFromDir($$DIRECTORIES,*.ui) - -################################################################################ diff --git a/src/OpenMesh/Examples/Tutorial03/Tutorial03.pro b/src/OpenMesh/Examples/Tutorial03/Tutorial03.pro deleted file mode 100644 index 5d626522..00000000 --- a/src/OpenMesh/Examples/Tutorial03/Tutorial03.pro +++ /dev/null @@ -1,19 +0,0 @@ -################################################################################ -# -################################################################################ - -include( $$TOPDIR/qmake/all.include ) - -INCLUDEPATH += ../../.. - -Application() -openmesh() - -DIRECTORIES = . - -# Input -HEADERS += $$getFilesFromDir($$DIRECTORIES,*.hh) -SOURCES += $$getFilesFromDir($$DIRECTORIES,*.cc) -FORMS += $$getFilesFromDir($$DIRECTORIES,*.ui) - -################################################################################ diff --git a/src/OpenMesh/Examples/Tutorial04/Tutorial04.pro b/src/OpenMesh/Examples/Tutorial04/Tutorial04.pro deleted file mode 100644 index 5d626522..00000000 --- a/src/OpenMesh/Examples/Tutorial04/Tutorial04.pro +++ /dev/null @@ -1,19 +0,0 @@ -################################################################################ -# -################################################################################ - -include( $$TOPDIR/qmake/all.include ) - -INCLUDEPATH += ../../.. - -Application() -openmesh() - -DIRECTORIES = . - -# Input -HEADERS += $$getFilesFromDir($$DIRECTORIES,*.hh) -SOURCES += $$getFilesFromDir($$DIRECTORIES,*.cc) -FORMS += $$getFilesFromDir($$DIRECTORIES,*.ui) - -################################################################################ diff --git a/src/OpenMesh/Examples/Tutorial04/smooth_algo.hh b/src/OpenMesh/Examples/Tutorial04/smooth_algo.hh index 9c564427..788b8b73 100644 --- a/src/OpenMesh/Examples/Tutorial04/smooth_algo.hh +++ b/src/OpenMesh/Examples/Tutorial04/smooth_algo.hh @@ -13,7 +13,7 @@ public: public: // construct with a given mesh - SmootherT(Mesh& _mesh) + explicit SmootherT(Mesh& _mesh) : mesh_(_mesh) { mesh_.add_property( cog_ ); diff --git a/src/OpenMesh/Examples/Tutorial05/Tutorial05.pro b/src/OpenMesh/Examples/Tutorial05/Tutorial05.pro deleted file mode 100644 index 5d626522..00000000 --- a/src/OpenMesh/Examples/Tutorial05/Tutorial05.pro +++ /dev/null @@ -1,19 +0,0 @@ -################################################################################ -# -################################################################################ - -include( $$TOPDIR/qmake/all.include ) - -INCLUDEPATH += ../../.. - -Application() -openmesh() - -DIRECTORIES = . - -# Input -HEADERS += $$getFilesFromDir($$DIRECTORIES,*.hh) -SOURCES += $$getFilesFromDir($$DIRECTORIES,*.cc) -FORMS += $$getFilesFromDir($$DIRECTORIES,*.ui) - -################################################################################ diff --git a/src/OpenMesh/Examples/Tutorial06/Tutorial06.pro b/src/OpenMesh/Examples/Tutorial06/Tutorial06.pro deleted file mode 100644 index 5d626522..00000000 --- a/src/OpenMesh/Examples/Tutorial06/Tutorial06.pro +++ /dev/null @@ -1,19 +0,0 @@ -################################################################################ -# -################################################################################ - -include( $$TOPDIR/qmake/all.include ) - -INCLUDEPATH += ../../.. - -Application() -openmesh() - -DIRECTORIES = . - -# Input -HEADERS += $$getFilesFromDir($$DIRECTORIES,*.hh) -SOURCES += $$getFilesFromDir($$DIRECTORIES,*.cc) -FORMS += $$getFilesFromDir($$DIRECTORIES,*.ui) - -################################################################################ diff --git a/src/OpenMesh/Examples/Tutorial07/Tutorial07.pro b/src/OpenMesh/Examples/Tutorial07/Tutorial07.pro deleted file mode 100644 index 5d626522..00000000 --- a/src/OpenMesh/Examples/Tutorial07/Tutorial07.pro +++ /dev/null @@ -1,19 +0,0 @@ -################################################################################ -# -################################################################################ - -include( $$TOPDIR/qmake/all.include ) - -INCLUDEPATH += ../../.. - -Application() -openmesh() - -DIRECTORIES = . - -# Input -HEADERS += $$getFilesFromDir($$DIRECTORIES,*.hh) -SOURCES += $$getFilesFromDir($$DIRECTORIES,*.cc) -FORMS += $$getFilesFromDir($$DIRECTORIES,*.ui) - -################################################################################ diff --git a/src/OpenMesh/Examples/Tutorial08/Tutorial08.pro b/src/OpenMesh/Examples/Tutorial08/Tutorial08.pro deleted file mode 100644 index 5d626522..00000000 --- a/src/OpenMesh/Examples/Tutorial08/Tutorial08.pro +++ /dev/null @@ -1,19 +0,0 @@ -################################################################################ -# -################################################################################ - -include( $$TOPDIR/qmake/all.include ) - -INCLUDEPATH += ../../.. - -Application() -openmesh() - -DIRECTORIES = . - -# Input -HEADERS += $$getFilesFromDir($$DIRECTORIES,*.hh) -SOURCES += $$getFilesFromDir($$DIRECTORIES,*.cc) -FORMS += $$getFilesFromDir($$DIRECTORIES,*.ui) - -################################################################################ diff --git a/src/OpenMesh/Examples/Tutorial08/delete_geometry.cc b/src/OpenMesh/Examples/Tutorial08/delete_geometry.cc index 10fe08f3..5614bf31 100644 --- a/src/OpenMesh/Examples/Tutorial08/delete_geometry.cc +++ b/src/OpenMesh/Examples/Tutorial08/delete_geometry.cc @@ -39,13 +39,6 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision: 1258 $ * - * $Date: 2015-04-28 15:07:46 +0200 (Di, 28 Apr 2015) $ * - * * - \*===========================================================================*/ - #include // -------------------- OpenMesh diff --git a/src/OpenMesh/Examples/Tutorial09/Tutorial09.pro b/src/OpenMesh/Examples/Tutorial09/Tutorial09.pro deleted file mode 100644 index 5d626522..00000000 --- a/src/OpenMesh/Examples/Tutorial09/Tutorial09.pro +++ /dev/null @@ -1,19 +0,0 @@ -################################################################################ -# -################################################################################ - -include( $$TOPDIR/qmake/all.include ) - -INCLUDEPATH += ../../.. - -Application() -openmesh() - -DIRECTORIES = . - -# Input -HEADERS += $$getFilesFromDir($$DIRECTORIES,*.hh) -SOURCES += $$getFilesFromDir($$DIRECTORIES,*.cc) -FORMS += $$getFilesFromDir($$DIRECTORIES,*.ui) - -################################################################################ diff --git a/src/OpenMesh/Examples/Tutorial10/Tutorial10.pro b/src/OpenMesh/Examples/Tutorial10/Tutorial10.pro deleted file mode 100644 index 5d626522..00000000 --- a/src/OpenMesh/Examples/Tutorial10/Tutorial10.pro +++ /dev/null @@ -1,19 +0,0 @@ -################################################################################ -# -################################################################################ - -include( $$TOPDIR/qmake/all.include ) - -INCLUDEPATH += ../../.. - -Application() -openmesh() - -DIRECTORIES = . - -# Input -HEADERS += $$getFilesFromDir($$DIRECTORIES,*.hh) -SOURCES += $$getFilesFromDir($$DIRECTORIES,*.cc) -FORMS += $$getFilesFromDir($$DIRECTORIES,*.ui) - -################################################################################ diff --git a/src/OpenMesh/Tools/CMakeLists.txt b/src/OpenMesh/Tools/CMakeLists.txt index 728a367a..fcba8a94 100644 --- a/src/OpenMesh/Tools/CMakeLists.txt +++ b/src/OpenMesh/Tools/CMakeLists.txt @@ -1,132 +1,126 @@ -include (ACGCommon) - -include_directories ( - ../.. - ${CMAKE_CURRENT_SOURCE_DIR} -) - -# source code directories -set (directories - . - Decimater - Dualizer - Smoother - Subdivider/Adaptive/Composite - Subdivider/Uniform/Composite - Subdivider/Uniform - Utils - VDPM -) - -# collect all header and source files -acg_append_files (headers "*.hh" ${directories}) -acg_append_files (sources "*.cc" ${directories}) - -#Drop the template only cc files -acg_drop_templates(sources) - -IF(WIN32 AND NOT MINGW) - acg_append_files (sources "*.c" ${directories}) -ENDIF(WIN32 AND NOT MINGW) - -# Disable Library installation when not building OpenMesh on its own but as part of another project! -if ( NOT ${PROJECT_NAME} MATCHES "OpenMesh") - set(ACG_NO_LIBRARY_INSTALL true) -endif() - - -if (WIN32) - - if ( OPENMESH_BUILD_SHARED ) - add_definitions( -DOPENMESHDLL -DBUILDOPENMESHDLL) - acg_add_library (OpenMeshTools SHARED ${sources} ${headers}) - else() - # OpenMesh has no dll exports so we have to build a static library on windows - acg_add_library (OpenMeshTools STATIC ${sources} ${headers}) - endif() - -else () - acg_add_library (OpenMeshTools SHAREDANDSTATIC ${sources} ${headers}) - set_target_properties (OpenMeshTools PROPERTIES VERSION ${OPENMESH_VERSION_MAJOR}.${OPENMESH_VERSION_MINOR} - SOVERSION ${OPENMESH_VERSION_MAJOR}.${OPENMESH_VERSION_MINOR} ) -endif () - -target_link_libraries (OpenMeshTools OpenMeshCore) - -IF( NOT WIN32 ) - target_link_libraries (OpenMeshToolsStatic OpenMeshCoreStatic) -ENDIF(NOT WIN32) - -if ( (${PROJECT_NAME} MATCHES "OpenMesh") AND BUILD_APPS ) - - if ( WIN32 ) - if ( NOT "${CMAKE_GENERATOR}" MATCHES "MinGW Makefiles" ) - # let bundle generation depend on target - add_dependencies (fixbundle OpenMeshTools) - endif() - endif() - - # Add tools as dependency before fixbundle - if (APPLE) - # let bundle generation depend on target - add_dependencies (fixbundle OpenMeshTools) - add_dependencies (fixbundle OpenMeshToolsStatic) - endif() - -endif() - - -# Install Header Files (Apple) -if ( NOT ACG_PROJECT_MACOS_BUNDLE AND APPLE ) - FILE(GLOB files_install_Decimater "${CMAKE_CURRENT_SOURCE_DIR}/Decimater/*.hh" "${CMAKE_CURRENT_SOURCE_DIR}/Decimater/*T.cc" ) - FILE(GLOB files_install_Dualizer "${CMAKE_CURRENT_SOURCE_DIR}/Dualizer/*.hh" "${CMAKE_CURRENT_SOURCE_DIR}/Dualizer/*T.cc" ) - FILE(GLOB files_install_KERNEL_OSG "${CMAKE_CURRENT_SOURCE_DIR}/Kernel_OSG/*.hh" "${CMAKE_CURRENT_SOURCE_DIR}/Kernel_OSG/*T.cc" ) - FILE(GLOB files_install_Smoother "${CMAKE_CURRENT_SOURCE_DIR}/Smoother/*.hh" "${CMAKE_CURRENT_SOURCE_DIR}/Smoother/*T.cc" ) - FILE(GLOB files_install_Subdivider_Adaptive "${CMAKE_CURRENT_SOURCE_DIR}/Subdivider/Adaptive/Composite/*.hh" "${CMAKE_CURRENT_SOURCE_DIR}/Subdivider/Adaptive/Composite/*T.cc" ) - FILE(GLOB files_install_Subdivider_Uniform "${CMAKE_CURRENT_SOURCE_DIR}/Subdivider/Uniform/*.hh" "${CMAKE_CURRENT_SOURCE_DIR}/Subdivider/Uniform/*T.cc" ) - FILE(GLOB files_install_Subdivider_Uniform_Composite "${CMAKE_CURRENT_SOURCE_DIR}/Subdivider/Uniform/Composite/*.hh" "${CMAKE_CURRENT_SOURCE_DIR}/Subdivider/Uniform/Composite/*T.cc" ) - FILE(GLOB files_install_Utils "${CMAKE_CURRENT_SOURCE_DIR}/Utils/*.hh" "${CMAKE_CURRENT_SOURCE_DIR}/Utils/*T.cc" "${CMAKE_CURRENT_SOURCE_DIR}/Utils/getopt.h" ) - FILE(GLOB files_install_VDPM "${CMAKE_CURRENT_SOURCE_DIR}/VDPM/*.hh" "${CMAKE_CURRENT_SOURCE_DIR}/VDPM/*T.cc" ) - INSTALL(FILES ${files_install_Decimater} DESTINATION include/OpenMesh/Tools/Decimater ) - INSTALL(FILES ${files_install_Dualizer} DESTINATION include/OpenMesh/Tools/Dualizer ) - INSTALL(FILES ${files_install_KERNEL_OSG} DESTINATION include/OpenMesh/Tools/Kernel_OSG ) - INSTALL(FILES ${files_install_Smoother} DESTINATION include/OpenMesh/Tools/Smoother ) - INSTALL(FILES ${files_install_Subdivider_Adaptive} DESTINATION include/OpenMesh/Tools/Subdivider/Adaptive/Composite ) - INSTALL(FILES ${files_install_Subdivider_Uniform} DESTINATION include/OpenMesh/Tools/Subdivider/Uniform ) - INSTALL(FILES ${files_install_Subdivider_Uniform_Composite} DESTINATION include/OpenMesh/Tools/Subdivider/Uniform/Composite ) - INSTALL(FILES ${files_install_Utils} DESTINATION include/OpenMesh/Tools/Utils ) - INSTALL(FILES ${files_install_VDPM} DESTINATION include/OpenMesh/Tools/VDPM ) -endif() - - -# Only install if the project name matches OpenMesh. -if (NOT APPLE AND ${PROJECT_NAME} MATCHES "OpenMesh") - -# Install Header Files -install(DIRECTORY . - DESTINATION include/OpenMesh/Tools - FILES_MATCHING - PATTERN "*.hh" - PATTERN "CVS" EXCLUDE - PATTERN ".svn" EXCLUDE - PATTERN "tmp" EXCLUDE - PATTERN "Templates" EXCLUDE - PATTERN "Debian*" EXCLUDE) - -#install Template cc files (required by headers) -install(DIRECTORY . - DESTINATION include/OpenMesh/Tools - FILES_MATCHING - PATTERN "*T.cc" - PATTERN "CVS" EXCLUDE - PATTERN ".svn" EXCLUDE - PATTERN "tmp" EXCLUDE - PATTERN "Templates" EXCLUDE - PATTERN "Debian*" EXCLUDE) - -#install the config file -install(FILES Utils/getopt.h DESTINATION include/OpenMesh/Tools/Utils) - -endif () - - +include (ACGCommon) + +include_directories ( + ../.. + ${CMAKE_CURRENT_SOURCE_DIR} +) + +# source code directories +set (directories + . + Decimater + Dualizer + Smoother + Subdivider/Adaptive/Composite + Subdivider/Uniform/Composite + Subdivider/Uniform + Utils + VDPM +) + +# collect all header and source files +acg_append_files (headers "*.hh" ${directories}) +acg_append_files (sources "*.cc" ${directories}) + +IF(WIN32 AND NOT MINGW) + acg_append_files (sources "*.c" ${directories}) +ENDIF(WIN32 AND NOT MINGW) + +# Disable Library installation when not building OpenMesh on its own but as part of another project! +if ( NOT ${PROJECT_NAME} MATCHES "OpenMesh") + set(ACG_NO_LIBRARY_INSTALL true) +endif() + + +if (WIN32) + + if ( OPENMESH_BUILD_SHARED ) + add_definitions( -DOPENMESHDLL -DBUILDOPENMESHDLL) + acg_add_library (OpenMeshTools SHARED ${sources} ${headers}) + else() + # OpenMesh has no dll exports so we have to build a static library on windows + acg_add_library (OpenMeshTools STATIC ${sources} ${headers}) + endif() + +else () + acg_add_library (OpenMeshTools SHAREDANDSTATIC ${sources} ${headers}) + set_target_properties (OpenMeshTools PROPERTIES VERSION ${OPENMESH_VERSION_MAJOR}.${OPENMESH_VERSION_MINOR} + SOVERSION ${OPENMESH_VERSION_MAJOR}.${OPENMESH_VERSION_MINOR} ) +endif () + +target_link_libraries (OpenMeshTools OpenMeshCore) + +IF( NOT WIN32 ) + target_link_libraries (OpenMeshToolsStatic OpenMeshCoreStatic) +ENDIF(NOT WIN32) + +if ( (${PROJECT_NAME} MATCHES "OpenMesh") AND BUILD_APPS ) + + if ( WIN32 ) + if ( NOT "${CMAKE_GENERATOR}" MATCHES "MinGW Makefiles" ) + # let bundle generation depend on target + add_dependencies (fixbundle OpenMeshTools) + endif() + endif() + + # Add tools as dependency before fixbundle + if (APPLE) + # let bundle generation depend on target + add_dependencies (fixbundle OpenMeshTools) + add_dependencies (fixbundle OpenMeshToolsStatic) + endif() + +endif() + + +# Install Header Files (Apple) +if ( NOT ACG_PROJECT_MACOS_BUNDLE AND APPLE ) + FILE(GLOB files_install_Decimater "${CMAKE_CURRENT_SOURCE_DIR}/Decimater/*.hh" ) + FILE(GLOB files_install_Dualizer "${CMAKE_CURRENT_SOURCE_DIR}/Dualizer/*.hh" ) + FILE(GLOB files_install_KERNEL_OSG "${CMAKE_CURRENT_SOURCE_DIR}/Kernel_OSG/*.hh" ) + FILE(GLOB files_install_Smoother "${CMAKE_CURRENT_SOURCE_DIR}/Smoother/*.hh" ) + FILE(GLOB files_install_Subdivider_Adaptive "${CMAKE_CURRENT_SOURCE_DIR}/Subdivider/Adaptive/Composite/*.hh" ) + FILE(GLOB files_install_Subdivider_Uniform "${CMAKE_CURRENT_SOURCE_DIR}/Subdivider/Uniform/*.hh" ) + FILE(GLOB files_install_Subdivider_Uniform_Composite "${CMAKE_CURRENT_SOURCE_DIR}/Subdivider/Uniform/Composite/*.hh" ) + FILE(GLOB files_install_Utils "${CMAKE_CURRENT_SOURCE_DIR}/Utils/*.hh" "${CMAKE_CURRENT_SOURCE_DIR}/Utils/getopt.h" ) + FILE(GLOB files_install_VDPM "${CMAKE_CURRENT_SOURCE_DIR}/VDPM/*.hh" ) + INSTALL(FILES ${files_install_Decimater} DESTINATION include/OpenMesh/Tools/Decimater ) + INSTALL(FILES ${files_install_Dualizer} DESTINATION include/OpenMesh/Tools/Dualizer ) + INSTALL(FILES ${files_install_KERNEL_OSG} DESTINATION include/OpenMesh/Tools/Kernel_OSG ) + INSTALL(FILES ${files_install_Smoother} DESTINATION include/OpenMesh/Tools/Smoother ) + INSTALL(FILES ${files_install_Subdivider_Adaptive} DESTINATION include/OpenMesh/Tools/Subdivider/Adaptive/Composite ) + INSTALL(FILES ${files_install_Subdivider_Uniform} DESTINATION include/OpenMesh/Tools/Subdivider/Uniform ) + INSTALL(FILES ${files_install_Subdivider_Uniform_Composite} DESTINATION include/OpenMesh/Tools/Subdivider/Uniform/Composite ) + INSTALL(FILES ${files_install_Utils} DESTINATION include/OpenMesh/Tools/Utils ) + INSTALL(FILES ${files_install_VDPM} DESTINATION include/OpenMesh/Tools/VDPM ) +endif() + + +# Only install if the project name matches OpenMesh. +if (NOT APPLE AND ${PROJECT_NAME} MATCHES "OpenMesh") + +# Install Header Files +install(DIRECTORY . + DESTINATION include/OpenMesh/Tools + FILES_MATCHING + PATTERN "*.hh" + PATTERN "CVS" EXCLUDE + PATTERN ".svn" EXCLUDE + PATTERN "tmp" EXCLUDE + PATTERN "Templates" EXCLUDE + PATTERN "Debian*" EXCLUDE) + +#install the config file +install(FILES Utils/getopt.h DESTINATION include/OpenMesh/Tools/Utils) + +endif () + +target_include_directories(OpenMeshTools PUBLIC + $ + $) + +install(TARGETS OpenMeshTools EXPORT OpenMeshConfig + ARCHIVE DESTINATION ${ACG_PROJECT_LIBDIR} + LIBRARY DESTINATION ${ACG_PROJECT_LIBDIR} + RUNTIME DESTINATION ${ACG_PROJECT_BINDIR}) + diff --git a/src/OpenMesh/Tools/Decimater/BaseDecimaterT.hh b/src/OpenMesh/Tools/Decimater/BaseDecimaterT.hh index 3006f6ae..0d2cf864 100644 --- a/src/OpenMesh/Tools/Decimater/BaseDecimaterT.hh +++ b/src/OpenMesh/Tools/Decimater/BaseDecimaterT.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + /** \file BaseDecimaterT.hh */ @@ -99,7 +94,7 @@ public: //-------------------------------------------------------- public types typedef typename ModuleList::iterator ModuleListIterator; public: //------------------------------------------------------ public methods - BaseDecimaterT(Mesh& _mesh); + explicit BaseDecimaterT(Mesh& _mesh); virtual ~BaseDecimaterT(); /** Initialize decimater and decimating modules. @@ -282,7 +277,7 @@ private: //------------------------------------------------------- private data //============================================================================= #if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_BASE_DECIMATER_DECIMATERT_CC) #define OPENMESH_BASE_DECIMATER_TEMPLATES -#include "BaseDecimaterT.cc" +#include "BaseDecimaterT_impl.hh" #endif //============================================================================= #endif // OPENMESH_BASE_DECIMATER_DECIMATERT_HH defined diff --git a/src/OpenMesh/Tools/Decimater/BaseDecimaterT.cc b/src/OpenMesh/Tools/Decimater/BaseDecimaterT_impl.hh similarity index 94% rename from src/OpenMesh/Tools/Decimater/BaseDecimaterT.cc rename to src/OpenMesh/Tools/Decimater/BaseDecimaterT_impl.hh index b36778fe..68d57b09 100644 --- a/src/OpenMesh/Tools/Decimater/BaseDecimaterT.cc +++ b/src/OpenMesh/Tools/Decimater/BaseDecimaterT_impl.hh @@ -39,14 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * - \*===========================================================================*/ - -/** \file DecimaterT.cc +/** \file DecimaterT_impl.cc */ //============================================================================= @@ -74,7 +67,7 @@ namespace Decimater { template BaseDecimaterT::BaseDecimaterT(Mesh& _mesh) : - mesh_(_mesh), cmodule_(NULL), initialized_(false), observer_(NULL) { + mesh_(_mesh), cmodule_(nullptr), initialized_(false), observer_(nullptr) { // default properties mesh_.request_vertex_status(); mesh_.request_edge_status(); @@ -256,8 +249,8 @@ bool BaseDecimaterT::initialize() { // priority module explicitly. // find the priority module: either the only non-binary module in the list, or "Quadric" - Module *quadric = NULL; - Module *pmodule = NULL; + Module *quadric = nullptr; + Module *pmodule = nullptr; for (ModuleListIterator m_it = all_modules_.begin(), m_end = all_modules_.end(); m_it != m_end; ++m_it) { if ((*m_it)->name() == "Quadric") diff --git a/src/OpenMesh/Tools/Decimater/CollapseInfoT.hh b/src/OpenMesh/Tools/Decimater/CollapseInfoT.hh index 4212e822..ed648bc4 100644 --- a/src/OpenMesh/Tools/Decimater/CollapseInfoT.hh +++ b/src/OpenMesh/Tools/Decimater/CollapseInfoT.hh @@ -39,12 +39,6 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * - \*===========================================================================*/ /** \file CollapseInfoT.hh Provides data class CollapseInfoT for storing all information diff --git a/src/OpenMesh/Tools/Decimater/DecimaterT.hh b/src/OpenMesh/Tools/Decimater/DecimaterT.hh index 55cf080f..6d0b3b4d 100644 --- a/src/OpenMesh/Tools/Decimater/DecimaterT.hh +++ b/src/OpenMesh/Tools/Decimater/DecimaterT.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + /** \file DecimaterT.hh */ @@ -94,7 +89,7 @@ public: //-------------------------------------------------------- public types public: //------------------------------------------------------ public methods /// Constructor - DecimaterT( Mesh& _mesh ); + explicit DecimaterT( Mesh& _mesh ); /// Destructor ~DecimaterT(); @@ -105,26 +100,28 @@ public: * @brief Perform a number of collapses on the mesh. * @param _n_collapses Desired number of collapses. If zero (default), attempt * to do as many collapses as possible. + * @param _only_selected Only consider vertices which are selected for decimation * @return Number of collapses that were actually performed. * @note This operation only marks the removed mesh elements for deletion. In * order to actually remove the decimated elements from the mesh, a * subsequent call to ArrayKernel::garbage_collection() is required. */ - size_t decimate( size_t _n_collapses = 0 ); + size_t decimate( size_t _n_collapses = 0 , bool _only_selected = false); /** * @brief Decimate the mesh to a desired target vertex complexity. * @param _n_vertices Target complexity, i.e. desired number of remaining * vertices after decimation. + * @param _only_selected Only consider vertices which are selected for decimation * @return Number of collapses that were actually performed. * @note This operation only marks the removed mesh elements for deletion. In * order to actually remove the decimated elements from the mesh, a * subsequent call to ArrayKernel::garbage_collection() is required. */ - size_t decimate_to( size_t _n_vertices ) + size_t decimate_to( size_t _n_vertices , bool _only_selected = false) { return ( (_n_vertices < this->mesh().n_vertices()) ? - decimate( this->mesh().n_vertices() - _n_vertices ) : 0 ); + decimate( this->mesh().n_vertices() - _n_vertices , _only_selected ) : 0 ); } /** @@ -132,6 +129,7 @@ public: * complexity is achieved. * @param _n_vertices Target vertex complexity. * @param _n_faces Target face complexity. + * @param _only_selected Only consider vertices which are selected for decimation * @return Number of collapses that were actually performed. * @note Decimation stops as soon as either one of the two complexity bounds * is satisfied. @@ -139,7 +137,7 @@ public: * order to actually remove the decimated elements from the mesh, a * subsequent call to ArrayKernel::garbage_collection() is required. */ - size_t decimate_to_faces( size_t _n_vertices=0, size_t _n_faces=0 ); + size_t decimate_to_faces( size_t _n_vertices=0, size_t _n_faces=0 , bool _only_selected = false); public: @@ -214,7 +212,7 @@ private: //------------------------------------------------------- private data //============================================================================= #if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_DECIMATER_DECIMATERT_CC) #define OPENMESH_DECIMATER_TEMPLATES -#include "DecimaterT.cc" +#include "DecimaterT_impl.hh" #endif //============================================================================= #endif // OPENMESH_DECIMATER_DECIMATERT_HH defined diff --git a/src/OpenMesh/Tools/Decimater/DecimaterT.cc b/src/OpenMesh/Tools/Decimater/DecimaterT_impl.hh similarity index 91% rename from src/OpenMesh/Tools/Decimater/DecimaterT.cc rename to src/OpenMesh/Tools/Decimater/DecimaterT_impl.hh index 2ca41a7c..c38d4272 100644 --- a/src/OpenMesh/Tools/Decimater/DecimaterT.cc +++ b/src/OpenMesh/Tools/Decimater/DecimaterT_impl.hh @@ -39,14 +39,8 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * - \*===========================================================================*/ -/** \file DecimaterT.cc +/** \file DecimaterT_impl.hh */ //============================================================================= @@ -81,7 +75,7 @@ DecimaterT::DecimaterT(Mesh& _mesh) : #if (defined(_MSC_VER) && (_MSC_VER >= 1800)) || __cplusplus > 199711L || defined( __GXX_EXPERIMENTAL_CXX0X__ ) heap_(nullptr) #else - heap_(NULL) + heap_(nullptr) #endif { @@ -150,15 +144,14 @@ void DecimaterT::heap_vertex(VertexHandle _vh) { mesh_.property(priority_, _vh) = -1; } } - -//----------------------------------------------------------------------------- -template -size_t DecimaterT::decimate(size_t _n_collapses) { - - if (!this->is_initialized()) - return 0; - typename Mesh::VertexIter v_it, v_end(mesh_.vertices_end()); +//----------------------------------------------------------------------------- +template +size_t DecimaterT::decimate(size_t _n_collapses, bool _only_selected) { + + if (!this->is_initialized()) + return 0; + typename Mesh::VertexHandle vp; typename Mesh::HalfedgeHandle v0v1; typename Mesh::VertexVertexIter vv_it; @@ -187,10 +180,15 @@ size_t DecimaterT::decimate(size_t _n_collapses) { heap_->reserve(mesh_.n_vertices()); - for (v_it = mesh_.vertices_begin(); v_it != v_end; ++v_it) { - heap_->reset_heap_position(*v_it); - if (!mesh_.status(*v_it).deleted()) - heap_vertex(*v_it); + for ( auto v_it : mesh_.vertices() ) { + heap_->reset_heap_position(v_it); + + if (!mesh_.status(v_it).deleted()) { + if (!_only_selected || mesh_.status(v_it).selected() ) { + heap_vertex(v_it); + } + } + } const bool update_normals = mesh_.has_face_normals(); @@ -236,16 +234,17 @@ size_t DecimaterT::decimate(size_t _n_collapses) { // update heap (former one ring of decimated vertex) for (s_it = support.begin(), s_end = support.end(); s_it != s_end; ++s_it) { - assert(!mesh_.status(*s_it).deleted()); - heap_vertex(*s_it); - } - - // notify observer and stop if the observer requests it - if (!this->notify_observer(n_collapses)) - return n_collapses; - } - - // delete heap + assert(!mesh_.status(*s_it).deleted()); + if (!_only_selected || mesh_.status(*s_it).selected() ) + heap_vertex(*s_it); + } + + // notify observer and stop if the observer requests it + if (!this->notify_observer(n_collapses)) + return n_collapses; + } + + // delete heap heap_.reset(); @@ -254,18 +253,17 @@ size_t DecimaterT::decimate(size_t _n_collapses) { return n_collapses; } -//----------------------------------------------------------------------------- - -template -size_t DecimaterT::decimate_to_faces(size_t _nv, size_t _nf) { - - if (!this->is_initialized()) - return 0; +//----------------------------------------------------------------------------- + +template +size_t DecimaterT::decimate_to_faces(size_t _nv, size_t _nf, bool _only_selected) { + + if (!this->is_initialized()) + return 0; if (_nv >= mesh_.n_vertices() || _nf >= mesh_.n_faces()) return 0; - typename Mesh::VertexIter v_it, v_end(mesh_.vertices_end()); typename Mesh::VertexHandle vp; typename Mesh::HalfedgeHandle v0v1; typename Mesh::VertexVertexIter vv_it; @@ -289,10 +287,13 @@ size_t DecimaterT::decimate_to_faces(size_t _nv, size_t _nf) { #endif heap_->reserve(mesh_.n_vertices()); - for (v_it = mesh_.vertices_begin(); v_it != v_end; ++v_it) { - heap_->reset_heap_position(*v_it); - if (!mesh_.status(*v_it).deleted()) - heap_vertex(*v_it); + for ( auto v_it : mesh_.vertices() ) { + heap_->reset_heap_position(v_it); + if (!mesh_.status(v_it).deleted()) { + if (!_only_selected || mesh_.status(v_it).selected() ) { + heap_vertex(v_it); + } + } } const bool update_normals = mesh_.has_face_normals(); @@ -345,16 +346,17 @@ size_t DecimaterT::decimate_to_faces(size_t _nv, size_t _nf) { // update heap (former one ring of decimated vertex) for (s_it = support.begin(), s_end = support.end(); s_it != s_end; ++s_it) { - assert(!mesh_.status(*s_it).deleted()); - heap_vertex(*s_it); - } - - // notify observer and stop if the observer requests it - if (!this->notify_observer(n_collapses)) - return n_collapses; - } - - // delete heap + assert(!mesh_.status(*s_it).deleted()); + if (!_only_selected || mesh_.status(*s_it).selected() ) + heap_vertex(*s_it); + } + + // notify observer and stop if the observer requests it + if (!this->notify_observer(n_collapses)) + return n_collapses; + } + + // delete heap heap_.reset(); diff --git a/src/OpenMesh/Tools/Decimater/McDecimaterT.hh b/src/OpenMesh/Tools/Decimater/McDecimaterT.hh index 82e1fd6b..553e311d 100644 --- a/src/OpenMesh/Tools/Decimater/McDecimaterT.hh +++ b/src/OpenMesh/Tools/Decimater/McDecimaterT.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + /** \file McDecimaterT.hh */ @@ -100,29 +95,56 @@ public: //------------------------------------------------------ public methods public: - /** Decimate (perform _n_collapses collapses). Return number of - performed collapses. If _n_collapses is not given reduce as - much as possible */ - size_t decimate( size_t _n_collapses ); + /** + * @brief Decimate (perform _n_collapses collapses). Return number of + * performed collapses. If _n_collapses is not given reduce as + * much as possible + * @param _n_collapses Desired number of collapses. If zero (default), attempt + * to do as many collapses as possible. + * @param _only_selected Only consider vertices which are selected for decimation + * @return Number of collapses that were actually performed. + * @note This operation only marks the removed mesh elements for deletion. In + * order to actually remove the decimated elements from the mesh, a + * subsequent call to ArrayKernel::garbage_collection() is required. + */ + size_t decimate( size_t _n_collapses , bool _only_selected = false); - /// Decimate to target complexity, returns number of collapses - size_t decimate_to( size_t _n_vertices ) + /** + * @brief Decimate the mesh to a desired target vertex complexity. + * @param _n_vertices Target complexity, i.e. desired number of remaining + * vertices after decimation. + * @param _only_selected Only consider vertices which are selected for decimation + * @return Number of collapses that were actually performed. + * @note This operation only marks the removed mesh elements for deletion. In + * order to actually remove the decimated elements from the mesh, a + * subsequent call to ArrayKernel::garbage_collection() is required. + */ + size_t decimate_to( size_t _n_vertices , bool _only_selected = false) { return ( (_n_vertices < this->mesh().n_vertices()) ? - decimate( this->mesh().n_vertices() - _n_vertices ) : 0 ); + decimate( this->mesh().n_vertices() - _n_vertices , _only_selected ) : 0 ); } - /** Decimate to target complexity (vertices and faces). - * Stops when the number of vertices or the number of faces is reached. - * Returns number of performed collapses. + /** + * @brief Attempts to decimate the mesh until a desired vertex or face + * complexity is achieved. + * @param _n_vertices Target vertex complexity. + * @param _n_faces Target face complexity. + * @param _only_selected Only consider vertices which are selected for decimation + * @return Number of collapses that were actually performed. + * @note Decimation stops as soon as either one of the two complexity bounds + * is satisfied. + * @note This operation only marks the removed mesh elements for deletion. In + * order to actually remove the decimated elements from the mesh, a + * subsequent call to ArrayKernel::garbage_collection() is required. */ - size_t decimate_to_faces( size_t _n_vertices=0, size_t _n_faces=0 ); + size_t decimate_to_faces( size_t _n_vertices=0, size_t _n_faces=0 , bool _only_selected = false); /** * Decimate only with constraints, while _factor gives the * percentage of the constraints that should be used */ - size_t decimate_constraints_only(float _factor); + size_t decimate_constraints_only(float _factor, bool _only_selected = false); size_t samples(){return randomSamples_;} void set_samples(const size_t _value){randomSamples_ = _value;} @@ -143,7 +165,7 @@ private: //------------------------------------------------------- private data //============================================================================= #if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_MULTIPLE_CHOICE_DECIMATER_DECIMATERT_CC) #define OPENMESH_MULTIPLE_CHOICE_DECIMATER_TEMPLATES -#include "McDecimaterT.cc" +#include "McDecimaterT_impl.hh" #endif //============================================================================= #endif // OPENMESH_MC_DECIMATER_DECIMATERT_HH defined diff --git a/src/OpenMesh/Tools/Decimater/McDecimaterT.cc b/src/OpenMesh/Tools/Decimater/McDecimaterT_impl.hh similarity index 95% rename from src/OpenMesh/Tools/Decimater/McDecimaterT.cc rename to src/OpenMesh/Tools/Decimater/McDecimaterT_impl.hh index 4dc813af..59b4fdf2 100644 --- a/src/OpenMesh/Tools/Decimater/McDecimaterT.cc +++ b/src/OpenMesh/Tools/Decimater/McDecimaterT_impl.hh @@ -39,14 +39,8 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * - \*===========================================================================*/ -/** \file McDecimaterT.cc +/** \file McDecimaterT_impl.hh */ //============================================================================= @@ -105,7 +99,7 @@ McDecimaterT::~McDecimaterT() { //----------------------------------------------------------------------------- template -size_t McDecimaterT::decimate(size_t _n_collapses) { +size_t McDecimaterT::decimate(size_t _n_collapses, bool _only_selected) { if (!this->is_initialized()) return 0; @@ -148,8 +142,8 @@ size_t McDecimaterT::decimate(size_t _n_collapses) { tmpHandle = typename Mesh::HalfedgeHandle( (double(rand()) / double(RAND_MAX) ) * double(mesh_.n_halfedges()-1) ); #endif - // if it is not deleted, we analyse it - if ( ! mesh_.status(tmpHandle).deleted() ) { + // if it is not deleted, we analyze it + if ( ! mesh_.status(tmpHandle).deleted() && (!_only_selected || mesh_.status(tmpHandle).selected() ) ) { CollapseInfo ci(mesh_, tmpHandle); @@ -229,7 +223,7 @@ size_t McDecimaterT::decimate(size_t _n_collapses) { //----------------------------------------------------------------------------- template -size_t McDecimaterT::decimate_to_faces(size_t _nv, size_t _nf) { +size_t McDecimaterT::decimate_to_faces(size_t _nv, size_t _nf, bool _only_selected) { if (!this->is_initialized()) return 0; @@ -279,8 +273,8 @@ size_t McDecimaterT::decimate_to_faces(size_t _nv, size_t _nf) { tmpHandle = typename Mesh::HalfedgeHandle( ( double(rand()) / double(RAND_MAX) ) * double(mesh_.n_halfedges() - 1)); #endif - // if it is not deleted, we analyse it - if (!mesh_.status(tmpHandle).deleted()) { + // if it is not deleted, we analyze it + if ( ! mesh_.status(tmpHandle).deleted() && (!_only_selected || mesh_.status(tmpHandle).selected() ) ) { CollapseInfo ci(mesh_, tmpHandle); @@ -372,7 +366,7 @@ size_t McDecimaterT::decimate_to_faces(size_t _nv, size_t _nf) { //----------------------------------------------------------------------------- template -size_t McDecimaterT::decimate_constraints_only(float _factor) { +size_t McDecimaterT::decimate_constraints_only(float _factor, bool _only_selected) { if (!this->is_initialized()) return 0; @@ -425,7 +419,8 @@ size_t McDecimaterT::decimate_constraints_only(float _factor) { #endif // if it is not deleted, we analyze it - if (!mesh_.status(mesh_.edge_handle(tmpHandle)).deleted()) { + if (!mesh_.status(mesh_.edge_handle(tmpHandle)).deleted() && + (!_only_selected || ( mesh_.status(mesh_.to_vertex_handle(tmpHandle)).selected() && mesh_.status(mesh_.from_vertex_handle(tmpHandle)).selected() ) ) ) { CollapseInfo ci(mesh_, tmpHandle); diff --git a/src/OpenMesh/Tools/Decimater/MixedDecimaterT.hh b/src/OpenMesh/Tools/Decimater/MixedDecimaterT.hh index cf52a5ad..7e3bbdbb 100644 --- a/src/OpenMesh/Tools/Decimater/MixedDecimaterT.hh +++ b/src/OpenMesh/Tools/Decimater/MixedDecimaterT.hh @@ -39,14 +39,8 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * - \*===========================================================================*/ -/** \file MixedDecimaterT.cc +/** \file MixedDecimaterT.hh */ //============================================================================= @@ -101,23 +95,61 @@ public: //------------------------------------------------------ public methods public: - /** Decimate (perform _n_collapses collapses). Return number of - performed collapses. If _n_collapses is not given reduce as - much as possible */ - size_t decimate( const size_t _n_collapses, const float _mc_factor ); + /** + * @brief Decimate (perform _n_collapses collapses). Return number of + * performed collapses. If _n_collapses is not given reduce as + * much as possible + * @param _n_collapses Desired number of collapses. If zero (default), attempt + * to do as many collapses as possible. + * @param _mc_factor Number between 0 and one defining how much percent of the + * collapses should be performed by MC Decimater before switching to + * Fixed decimation + * @param _only_selected Only consider vertices which are selected for decimation + * @return Number of collapses that were actually performed. + * @note This operation only marks the removed mesh elements for deletion. In + * order to actually remove the decimated elements from the mesh, a + * subsequent call to ArrayKernel::garbage_collection() is required. + */ + size_t decimate( const size_t _n_collapses, const float _mc_factor , bool _only_selected = false); - /// Decimate to target complexity, returns number of collapses - size_t decimate_to( size_t _n_vertices, const float _mc_factor ) + /** + * @brief Decimate the mesh to a desired target vertex complexity. + * @param _n_vertices Target complexity, i.e. desired number of remaining + * vertices after decimation. + + * @param _only_selected Only consider vertices which are selected for decimation + * @param _mc_factor Number between 0 and one defining how much percent of the + * collapses should be performed by MC Decimater before switching to + * Fixed decimation + * @return Number of collapses that were actually performed. + * @note This operation only marks the removed mesh elements for deletion. In + * order to actually remove the decimated elements from the mesh, a + * subsequent call to ArrayKernel::garbage_collection() is required. + */ + size_t decimate_to( size_t _n_vertices, const float _mc_factor , bool _only_selected = false) { return ( (_n_vertices < this->mesh().n_vertices()) ? - decimate( this->mesh().n_vertices() - _n_vertices, _mc_factor ) : 0 ); + decimate( this->mesh().n_vertices() - _n_vertices, _mc_factor , _only_selected) : 0 ); } - /** Decimate to target complexity (vertices and faces). - * Stops when the number of vertices or the number of faces is reached. - * Returns number of performed collapses. + /** + * @brief Attempts to decimate the mesh until a desired vertex or face + * complexity is achieved. + * @param _n_vertices Target vertex complexity. + * @param _n_faces Target face complexity. + * @param _mc_factor Number between 0 and one defining how much percent of the + * collapses should be performed by MC Decimater before switching to + * Fixed decimation + * @param _only_selected Only consider vertices which are selected for decimation + * @return Number of collapses that were actually performed. + * @note Decimation stops as soon as either one of the two complexity bounds + * is satisfied. + * @note This operation only marks the removed mesh elements for deletion. In + * order to actually remove the decimated elements from the mesh, a + * subsequent call to ArrayKernel::garbage_collection() is required. */ - size_t decimate_to_faces( const size_t _n_vertices=0, const size_t _n_faces=0 , const float _mc_factor = 0.8); + + size_t decimate_to_faces( const size_t _n_vertices=0, const size_t _n_faces=0 , const float _mc_factor = 0.8 , bool _only_selected = false); private: //------------------------------------------------------- private data @@ -129,7 +161,7 @@ private: //------------------------------------------------------- private data //============================================================================= #if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_MIXED_DECIMATER_DECIMATERT_CC) #define OPENMESH_MIXED_DECIMATER_TEMPLATES -#include "MixedDecimaterT.cc" +#include "MixedDecimaterT_impl.hh" #endif //============================================================================= #endif // OPENMESH_MIXED_DECIMATER_DECIMATERT_HH diff --git a/src/OpenMesh/Tools/Decimater/MixedDecimaterT.cc b/src/OpenMesh/Tools/Decimater/MixedDecimaterT_impl.hh similarity index 90% rename from src/OpenMesh/Tools/Decimater/MixedDecimaterT.cc rename to src/OpenMesh/Tools/Decimater/MixedDecimaterT_impl.hh index bb21f39d..e17882a6 100644 --- a/src/OpenMesh/Tools/Decimater/MixedDecimaterT.cc +++ b/src/OpenMesh/Tools/Decimater/MixedDecimaterT_impl.hh @@ -39,14 +39,8 @@ * * * ========================================================================= */ -/*===========================================================================*\ -* * -* $Revision$ * -* $Date$ * -* * -\*===========================================================================*/ -/** \file MixedDecimaterT.cc +/** \file MixedDecimaterT_impl.hh */ //============================================================================= @@ -88,7 +82,7 @@ MixedDecimaterT::~MixedDecimaterT() { //----------------------------------------------------------------------------- template -size_t MixedDecimaterT::decimate(const size_t _n_collapses, const float _mc_factor) { +size_t MixedDecimaterT::decimate(const size_t _n_collapses, const float _mc_factor, bool _only_selected) { if (_mc_factor > 1.0) return 0; @@ -98,21 +92,21 @@ size_t MixedDecimaterT::decimate(const size_t _n_collapses, const float _m size_t r_collapses = 0; if (_mc_factor > 0.0) - r_collapses = McDecimaterT::decimate(n_collapses_mc); + r_collapses = McDecimaterT::decimate(n_collapses_mc,_only_selected); // returns, if the previous steps were aborted by the observer if (this->observer() && this->observer()->abort()) return r_collapses; if (_mc_factor < 1.0) - r_collapses += DecimaterT::decimate(n_collapses_inc); + r_collapses += DecimaterT::decimate(n_collapses_inc,_only_selected); return r_collapses; } template -size_t MixedDecimaterT::decimate_to_faces(const size_t _n_vertices,const size_t _n_faces, const float _mc_factor ){ +size_t MixedDecimaterT::decimate_to_faces(const size_t _n_vertices,const size_t _n_faces, const float _mc_factor , bool _only_selected){ if (_mc_factor > 1.0) return 0; @@ -128,7 +122,7 @@ size_t MixedDecimaterT::decimate_to_faces(const size_t _n_vertices,const size_t n_vertices_mc = static_cast(mesh_vertices - _mc_factor * (mesh_vertices - _n_vertices)); size_t n_faces_mc = static_cast(mesh_faces - _mc_factor * (mesh_faces - _n_faces)); - r_collapses = McDecimaterT::decimate_to_faces(n_vertices_mc, n_faces_mc); + r_collapses = McDecimaterT::decimate_to_faces(n_vertices_mc, n_faces_mc,_only_selected); } else { const size_t samples = this->samples(); @@ -151,7 +145,7 @@ size_t MixedDecimaterT::decimate_to_faces(const size_t _n_vertices,const float decimaterLevel = (float(i + 1)) * _mc_factor / (float(steps) ); this->set_samples(samples); - r_collapses += McDecimaterT::decimate_constraints_only(decimaterLevel); + r_collapses += McDecimaterT::decimate_constraints_only(decimaterLevel,_only_selected); } } } @@ -165,7 +159,7 @@ size_t MixedDecimaterT::decimate_to_faces(const size_t _n_vertices,const //reduce the rest of the mesh if (_mc_factor < 1.0) { - r_collapses += DecimaterT::decimate_to_faces(_n_vertices,_n_faces); + r_collapses += DecimaterT::decimate_to_faces(_n_vertices,_n_faces,_only_selected); } diff --git a/src/OpenMesh/Tools/Decimater/ModAspectRatioT.hh b/src/OpenMesh/Tools/Decimater/ModAspectRatioT.hh index d22325f2..0213cbbb 100644 --- a/src/OpenMesh/Tools/Decimater/ModAspectRatioT.hh +++ b/src/OpenMesh/Tools/Decimater/ModAspectRatioT.hh @@ -39,12 +39,6 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * - \*===========================================================================*/ /** \file ModAspectRatioT.hh */ @@ -117,16 +111,16 @@ class ModAspectRatioT: public ModBaseT { } /// precompute face aspect ratio - void initialize(); + void initialize() override; /// Returns the collapse priority - float collapse_priority(const CollapseInfo& _ci); + float collapse_priority(const CollapseInfo& _ci) override; /// update aspect ratio of one-ring - void preprocess_collapse(const CollapseInfo& _ci); + void preprocess_collapse(const CollapseInfo& _ci) override; /// set percentage of aspect ratio - void set_error_tolerance_factor(double _factor); + void set_error_tolerance_factor(double _factor) override; private: @@ -148,7 +142,7 @@ class ModAspectRatioT: public ModBaseT { //============================================================================= #if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_DECIMATER_MODASPECTRATIOT_C) #define OPENMESH_DECIMATER_MODASPECTRATIOT_TEMPLATES -#include "ModAspectRatioT.cc" +#include "ModAspectRatioT_impl.hh" #endif //============================================================================= #endif // OPENMESH_DECIMATER_MODASPECTRATIOT_HH defined diff --git a/src/OpenMesh/Tools/Decimater/ModAspectRatioT.cc b/src/OpenMesh/Tools/Decimater/ModAspectRatioT_impl.hh similarity index 93% rename from src/OpenMesh/Tools/Decimater/ModAspectRatioT.cc rename to src/OpenMesh/Tools/Decimater/ModAspectRatioT_impl.hh index ec79f852..eebb2cc3 100644 --- a/src/OpenMesh/Tools/Decimater/ModAspectRatioT.cc +++ b/src/OpenMesh/Tools/Decimater/ModAspectRatioT_impl.hh @@ -39,14 +39,8 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * - \*===========================================================================*/ -/** \file ModAspectRatioT.cc +/** \file ModAspectRatioT_impl.hh */ //============================================================================= @@ -139,16 +133,16 @@ template float ModAspectRatioT::collapse_priority(const CollapseInfo& _ci) { typename Mesh::VertexHandle v2, v3; typename Mesh::FaceHandle fh; - const typename Mesh::Point *p1(&_ci.p1), *p2, *p3; + const typename Mesh::Point* p1(&_ci.p1); typename Mesh::Scalar r0, r1, r0_min(1.0), r1_min(1.0); typename Mesh::ConstVertexOHalfedgeIter voh_it(mesh_, _ci.v0); v3 = mesh_.to_vertex_handle(*voh_it); - p3 = &mesh_.point(v3); + auto p3 = &mesh_.point(v3); while (voh_it.is_valid()) { v2 = v3; - p2 = p3; + auto p2 = p3; ++voh_it; v3 = mesh_.to_vertex_handle(*voh_it); diff --git a/src/OpenMesh/Tools/Decimater/ModBaseT.hh b/src/OpenMesh/Tools/Decimater/ModBaseT.hh index 034ba5e9..f89e907e 100644 --- a/src/OpenMesh/Tools/Decimater/ModBaseT.hh +++ b/src/OpenMesh/Tools/Decimater/ModBaseT.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + /** \file ModBaseT.hh Base class for all decimation modules. @@ -95,14 +90,14 @@ public: public: /// Default constructor - ModHandleT() : mod_(NULL) {} + ModHandleT() : mod_(nullptr) {} /// Destructor ~ModHandleT() { /* don't delete mod_, since handle is not owner! */ } /// Check handle status /// \return \c true, if handle is valid, else \c false. - bool is_valid() const { return mod_ != NULL; } + bool is_valid() const { return mod_ != nullptr; } private: @@ -112,7 +107,7 @@ private: template friend class BaseDecimaterT; #endif - void clear() { mod_ = NULL; } + void clear() { mod_ = nullptr; } void init(Module* _m) { mod_ = _m; } Module* module() { return mod_; } @@ -133,7 +128,7 @@ private: /// Macro that sets up the name() function /// \internal #define DECIMATER_MODNAME(_mod_name) \ - virtual const std::string& name() const { \ + virtual const std::string& name() const override { \ static std::string _s_modname_(#_mod_name); return _s_modname_; \ } @@ -217,8 +212,8 @@ public: /// Virtual desctructor virtual ~ModBaseT() { } - /// Set module's name (using DECIMATER_MODNAME macro) - DECIMATER_MODNAME(ModBase); + /// Set module's name + virtual const std::string& name() const { static std::string _s_modname_("ModBase"); return _s_modname_; } /// Returns true if criteria returns a binary value. diff --git a/src/OpenMesh/Tools/Decimater/ModEdgeLengthT.hh b/src/OpenMesh/Tools/Decimater/ModEdgeLengthT.hh index f50878d3..e8e75a39 100644 --- a/src/OpenMesh/Tools/Decimater/ModEdgeLengthT.hh +++ b/src/OpenMesh/Tools/Decimater/ModEdgeLengthT.hh @@ -39,12 +39,6 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * - \*===========================================================================*/ /** \file ModEdgeLengthT.hh */ @@ -104,10 +98,10 @@ class ModEdgeLengthT: public ModBaseT { Cont. mode: Collapse smallest edge first, but don't collapse edges longer as edge_length_ */ - float collapse_priority(const CollapseInfo& _ci); + float collapse_priority(const CollapseInfo& _ci) override; /// set the percentage of edge length - void set_error_tolerance_factor(double _factor); + void set_error_tolerance_factor(double _factor) override; private: @@ -121,7 +115,7 @@ class ModEdgeLengthT: public ModBaseT { //============================================================================= #if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_DECIMATER_MODEDGELENGTHT_C) #define MODEDGELENGTHT_TEMPLATES -#include "ModEdgeLengthT.cc" +#include "ModEdgeLengthT_impl.hh" #endif //============================================================================= #endif // OPENMESH_DECIMATER_MODEDGELENGTHT_HH defined diff --git a/src/OpenMesh/Tools/Decimater/ModEdgeLengthT.cc b/src/OpenMesh/Tools/Decimater/ModEdgeLengthT_impl.hh similarity index 91% rename from src/OpenMesh/Tools/Decimater/ModEdgeLengthT.cc rename to src/OpenMesh/Tools/Decimater/ModEdgeLengthT_impl.hh index bfd45e52..084946f0 100644 --- a/src/OpenMesh/Tools/Decimater/ModEdgeLengthT.cc +++ b/src/OpenMesh/Tools/Decimater/ModEdgeLengthT_impl.hh @@ -39,14 +39,8 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * - \*===========================================================================*/ -/** \file ModEdgeLengthT.cc +/** \file ModEdgeLengthT_impl.hh */ //============================================================================= diff --git a/src/OpenMesh/Tools/Decimater/ModHausdorffT.hh b/src/OpenMesh/Tools/Decimater/ModHausdorffT.hh index caad8c5a..74c76373 100644 --- a/src/OpenMesh/Tools/Decimater/ModHausdorffT.hh +++ b/src/OpenMesh/Tools/Decimater/ModHausdorffT.hh @@ -39,12 +39,6 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * - \*===========================================================================*/ /** \file ModHausdorffT.hh */ @@ -114,7 +108,7 @@ class ModHausdorffT: public ModBaseT { } /// reset per-face point lists - virtual void initialize(); + virtual void initialize() override; /** \brief compute Hausdorff error for one-ring * @@ -126,13 +120,13 @@ class ModHausdorffT: public ModBaseT { * @return Binary return, if collapse is legal or illegal */ - virtual float collapse_priority(const CollapseInfo& _ci); + virtual float collapse_priority(const CollapseInfo& _ci) override; /// re-distribute points - virtual void postprocess_collapse(const CollapseInfo& _ci); + virtual void postprocess_collapse(const CollapseInfo& _ci) override; /// set the percentage of tolerance - void set_error_tolerance_factor(double _factor); + void set_error_tolerance_factor(double _factor) override; private: @@ -159,7 +153,7 @@ class ModHausdorffT: public ModBaseT { //============================================================================= #if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_DECIMATER_MODHAUSDORFFT_C) #define OPENMESH_DECIMATER_MODHAUSDORFFT_TEMPLATES -#include "ModHausdorffT.cc" +#include "ModHausdorffT_impl.hh" #endif //============================================================================= #endif // OPENMESH_DECIMATER_MODHAUSDORFFT_HH defined diff --git a/src/OpenMesh/Tools/Decimater/ModHausdorffT.cc b/src/OpenMesh/Tools/Decimater/ModHausdorffT_impl.hh similarity index 96% rename from src/OpenMesh/Tools/Decimater/ModHausdorffT.cc rename to src/OpenMesh/Tools/Decimater/ModHausdorffT_impl.hh index 3701a461..7985dc90 100644 --- a/src/OpenMesh/Tools/Decimater/ModHausdorffT.cc +++ b/src/OpenMesh/Tools/Decimater/ModHausdorffT_impl.hh @@ -39,14 +39,8 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ -/** \file ModHausdorffT.cc +/** \file ModHausdorffT_impl.hh */ @@ -262,7 +256,7 @@ collapse_priority(const CollapseInfo& _ci) // undo simulation changes mesh_.set_point(_ci.v0, _ci.p0); - return ( ok ? Base::LEGAL_COLLAPSE : Base::ILLEGAL_COLLAPSE ); + return ( ok ? static_cast(Base::LEGAL_COLLAPSE) : static_cast(Base::ILLEGAL_COLLAPSE) ); } //----------------------------------------------------------------------------- diff --git a/src/OpenMesh/Tools/Decimater/ModIndependentSetsT.hh b/src/OpenMesh/Tools/Decimater/ModIndependentSetsT.hh index e4d79f62..7a416af7 100644 --- a/src/OpenMesh/Tools/Decimater/ModIndependentSetsT.hh +++ b/src/OpenMesh/Tools/Decimater/ModIndependentSetsT.hh @@ -39,13 +39,6 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * - \*===========================================================================*/ - /** \file ModQuadricT.hh */ @@ -79,12 +72,12 @@ class ModIndependentSetsT: public ModBaseT { ; /// Constructor - ModIndependentSetsT(MeshT &_mesh) : + explicit ModIndependentSetsT(MeshT &_mesh) : Base(_mesh, true) { } /// override - void postprocess_collapse(const CollapseInfo& _ci) { + void postprocess_collapse(const CollapseInfo& _ci) override { typename Mesh::VertexVertexIter vv_it; Base::mesh().status(_ci.v1).set_locked(true); diff --git a/src/OpenMesh/Tools/Decimater/ModNormalDeviationT.hh b/src/OpenMesh/Tools/Decimater/ModNormalDeviationT.hh index 0415b042..b3ea88e7 100644 --- a/src/OpenMesh/Tools/Decimater/ModNormalDeviationT.hh +++ b/src/OpenMesh/Tools/Decimater/ModNormalDeviationT.hh @@ -39,12 +39,6 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ /** \file ModNormalDeviationT.hh */ @@ -103,7 +97,7 @@ public: typedef typename Mesh::VertexHandle VertexHandle; typedef typename Mesh::FaceHandle FaceHandle; typedef typename Mesh::EdgeHandle EdgeHandle; - typedef NormalConeT NormalCone; + typedef NormalConeT NormalCone; @@ -146,7 +140,7 @@ public: /// Allocate and init normal cones - void initialize() { + void initialize() override { if (!normal_cones_.is_valid()) mesh_.add_property(normal_cones_); @@ -171,7 +165,7 @@ public: * @param _ci Collapse info data * @return Half of the normal cones size (radius in radians) */ - float collapse_priority(const CollapseInfo& _ci) { + float collapse_priority(const CollapseInfo& _ci) override { // simulate collapse mesh_.set_point(_ci.v0, _ci.p1); @@ -209,20 +203,20 @@ public: } /// set the percentage of normal deviation - void set_error_tolerance_factor(double _factor) { + void set_error_tolerance_factor(double _factor) override { if (_factor >= 0.0 && _factor <= 1.0) { // the smaller the factor, the smaller normal_deviation_ gets // thus creating a stricter constraint // division by error_tolerance_factor_ is for normalization - Scalar normal_deviation = normal_deviation_ * static_cast( 180.0 / M_PI * _factor / this->error_tolerance_factor_); + Scalar normal_deviation_value = normal_deviation_ * static_cast( 180.0 / M_PI * _factor / this->error_tolerance_factor_); - set_normal_deviation(normal_deviation); + set_normal_deviation(normal_deviation_value); this->error_tolerance_factor_ = _factor; } } - void postprocess_collapse(const CollapseInfo& _ci) { + void postprocess_collapse(const CollapseInfo& _ci) override { // account for changed normals typename Mesh::VertexFaceIter vf_it(mesh_, _ci.v1); for (; vf_it.is_valid(); ++vf_it) diff --git a/src/OpenMesh/Tools/Decimater/ModNormalFlippingT.hh b/src/OpenMesh/Tools/Decimater/ModNormalFlippingT.hh index 2fd3a180..b2a00fd3 100644 --- a/src/OpenMesh/Tools/Decimater/ModNormalFlippingT.hh +++ b/src/OpenMesh/Tools/Decimater/ModNormalFlippingT.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + /** \file ModNormalFlippingT.hh @@ -91,7 +86,7 @@ public: public: /// Constructor - ModNormalFlippingT( MeshT &_mesh) : Base(_mesh, true) + explicit ModNormalFlippingT( MeshT &_mesh) : Base(_mesh, true) { set_max_normal_deviation( 90.0f ); const bool mesh_has_normals = _mesh.has_face_normals(); @@ -127,7 +122,7 @@ public: * * \see set_max_normal_deviation() */ - float collapse_priority(const CollapseInfo& _ci) + float collapse_priority(const CollapseInfo& _ci) override { // simulate collapse Base::mesh().set_point(_ci.v0, _ci.p1); @@ -159,13 +154,13 @@ public: } /// set the percentage of maximum normal deviation - void set_error_tolerance_factor(double _factor) { + void set_error_tolerance_factor(double _factor) override { if (_factor >= 0.0 && _factor <= 1.0) { // the smaller the factor, the smaller max_deviation_ gets // thus creating a stricter constraint // division by error_tolerance_factor_ is for normalization - double max_normal_deviation = (max_deviation_ * 180.0/M_PI) * _factor / this->error_tolerance_factor_; - set_max_normal_deviation(max_normal_deviation); + double max_normal_deviation_value = (max_deviation_ * 180.0/M_PI) * _factor / this->error_tolerance_factor_; + set_max_normal_deviation(max_normal_deviation_value); this->error_tolerance_factor_ = _factor; } } diff --git a/src/OpenMesh/Tools/Decimater/ModProgMeshT.hh b/src/OpenMesh/Tools/Decimater/ModProgMeshT.hh index 55325b40..dbedc07c 100644 --- a/src/OpenMesh/Tools/Decimater/ModProgMeshT.hh +++ b/src/OpenMesh/Tools/Decimater/ModProgMeshT.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + /** \file ModProgMeshT.hh @@ -95,7 +90,7 @@ public: { /// Initializing constructor copies appropriate handles from /// collapse information \c _ci. - Info( const CollapseInfo& _ci ) + explicit Info( const CollapseInfo& _ci ) : v0(_ci.v0), v1(_ci.v1), vl(_ci.vl),vr(_ci.vr) {} @@ -113,7 +108,7 @@ public: public: /// Constructor - ModProgMeshT( MeshT &_mesh ) : Base(_mesh, true) + explicit ModProgMeshT( MeshT &_mesh ) : Base(_mesh, true) { Base::mesh().add_property( idx_ ); } @@ -135,7 +130,7 @@ public: // inherited /// Stores collapse information in a queue. /// \see infolist() - void postprocess_collapse(const CollapseInfo& _ci) + void postprocess_collapse(const CollapseInfo& _ci) override { pmi_.push_back( Info( _ci ) ); } @@ -190,7 +185,7 @@ private: //============================================================================= #if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_DECIMATER_MODPROGMESH_CC) #define OSG_MODPROGMESH_TEMPLATES -#include "ModProgMeshT.cc" +#include "ModProgMeshT_impl.hh" #endif //============================================================================= #endif // OPENMESH_TOOLS_PROGMESHT_HH defined diff --git a/src/OpenMesh/Tools/Decimater/ModProgMeshT.cc b/src/OpenMesh/Tools/Decimater/ModProgMeshT_impl.hh similarity index 93% rename from src/OpenMesh/Tools/Decimater/ModProgMeshT.cc rename to src/OpenMesh/Tools/Decimater/ModProgMeshT_impl.hh index 04af1e91..1f657851 100644 --- a/src/OpenMesh/Tools/Decimater/ModProgMeshT.cc +++ b/src/OpenMesh/Tools/Decimater/ModProgMeshT_impl.hh @@ -39,14 +39,9 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ -/** \file ModProgMeshT.cc + +/** \file ModProgMeshT_impl.hh */ diff --git a/src/OpenMesh/Tools/Decimater/ModQuadricT.hh b/src/OpenMesh/Tools/Decimater/ModQuadricT.hh index 41835a84..2f431bf4 100644 --- a/src/OpenMesh/Tools/Decimater/ModQuadricT.hh +++ b/src/OpenMesh/Tools/Decimater/ModQuadricT.hh @@ -39,14 +39,6 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ - - //============================================================================= // // CLASS ModQuadricT @@ -93,7 +85,7 @@ public: /** Constructor * \internal */ - ModQuadricT( MeshT &_mesh ) + explicit ModQuadricT( MeshT &_mesh ) : Base(_mesh, false) { unset_max_err(); @@ -111,14 +103,14 @@ public: public: // inherited /// Initalize the module and prepare the mesh for decimation. - virtual void initialize(void); + virtual void initialize(void) override; /** Compute collapse priority based on error quadrics. * * \see ModBaseT::collapse_priority() for return values * \see set_max_err() */ - virtual float collapse_priority(const CollapseInfo& _ci) + virtual float collapse_priority(const CollapseInfo& _ci) override { using namespace OpenMesh; @@ -139,14 +131,14 @@ public: // inherited /// Post-process halfedge collapse (accumulate quadrics) - virtual void postprocess_collapse(const CollapseInfo& _ci) + virtual void postprocess_collapse(const CollapseInfo& _ci) override { Base::mesh().property(quadrics_, _ci.v1) += Base::mesh().property(quadrics_, _ci.v0); } /// set the percentage of maximum quadric error - void set_error_tolerance_factor(double _factor); + void set_error_tolerance_factor(double _factor) override; @@ -191,7 +183,7 @@ private: //============================================================================= #if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_DECIMATER_MODQUADRIC_CC) #define OSG_MODQUADRIC_TEMPLATES -#include "ModQuadricT.cc" +#include "ModQuadricT_impl.hh" #endif //============================================================================= #endif // OSG_MODQUADRIC_HH defined diff --git a/src/OpenMesh/Tools/Decimater/ModQuadricT.cc b/src/OpenMesh/Tools/Decimater/ModQuadricT_impl.hh similarity index 93% rename from src/OpenMesh/Tools/Decimater/ModQuadricT.cc rename to src/OpenMesh/Tools/Decimater/ModQuadricT_impl.hh index 0b461476..88ea66db 100644 --- a/src/OpenMesh/Tools/Decimater/ModQuadricT.cc +++ b/src/OpenMesh/Tools/Decimater/ModQuadricT_impl.hh @@ -39,14 +39,9 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ -/** \file ModQuadricT.cc + +/** \file ModQuadricT_impl.hh Bodies of template member function. */ diff --git a/src/OpenMesh/Tools/Decimater/ModRoundnessT.hh b/src/OpenMesh/Tools/Decimater/ModRoundnessT.hh index 622947bf..afd5ade4 100644 --- a/src/OpenMesh/Tools/Decimater/ModRoundnessT.hh +++ b/src/OpenMesh/Tools/Decimater/ModRoundnessT.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + /** \file ModRoundnessT.hh @@ -102,7 +97,7 @@ class ModRoundnessT : public ModBaseT public: /// Constructor - ModRoundnessT( MeshT &_dec ) : + explicit ModRoundnessT( MeshT &_dec ) : Base(_dec, false), min_r_(-1.0) { } @@ -122,7 +117,7 @@ class ModRoundnessT : public ModBaseT * \return LEGAL_COLLAPSE or ILLEGAL_COLLAPSE in binary mode * \see set_min_roundness() */ - float collapse_priority(const CollapseInfo& _ci) + float collapse_priority(const CollapseInfo& _ci) override { // using namespace OpenMesh; @@ -179,7 +174,7 @@ class ModRoundnessT : public ModBaseT } /// set the percentage of minimum roundness - void set_error_tolerance_factor(double _factor) { + void set_error_tolerance_factor(double _factor) override { if (this->is_binary()) { if (_factor >= 0.0 && _factor <= 1.0) { // the smaller the factor, the smaller min_r_ gets diff --git a/src/OpenMesh/Tools/Decimater/Observer.cc b/src/OpenMesh/Tools/Decimater/Observer.cc index 6a39e9c1..5e5c5939 100644 --- a/src/OpenMesh/Tools/Decimater/Observer.cc +++ b/src/OpenMesh/Tools/Decimater/Observer.cc @@ -39,12 +39,6 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision: 1197 $ * - * $Date: 2015-01-15 11:19:39 +0100 (Do, 15 Jan 2015) $ * - * * - \*===========================================================================*/ /** \file Observer.cc */ diff --git a/src/OpenMesh/Tools/Decimater/Observer.hh b/src/OpenMesh/Tools/Decimater/Observer.hh index f42b300d..d690209a 100644 --- a/src/OpenMesh/Tools/Decimater/Observer.hh +++ b/src/OpenMesh/Tools/Decimater/Observer.hh @@ -39,13 +39,6 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision: 1199 $ * - * $Date: 2015-01-16 08:47:33 +0100 (Fr, 16 Jan 2015) $ * - * * -\*===========================================================================*/ - /** \file Observer.hh * * This file contains an observer class which is used to monitor the progress diff --git a/src/OpenMesh/Tools/Dualizer/meshDualT.hh b/src/OpenMesh/Tools/Dualizer/meshDualT.hh index ab006f0d..4c221669 100644 --- a/src/OpenMesh/Tools/Dualizer/meshDualT.hh +++ b/src/OpenMesh/Tools/Dualizer/meshDualT.hh @@ -39,13 +39,6 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ - /* Compute the dual of a mesh: - each face of the original mesh is replaced by a vertex at the center of gravity of the vertices of the face diff --git a/src/OpenMesh/Tools/Kernel_OSG/ArrayKernelT.hh b/src/OpenMesh/Tools/Kernel_OSG/ArrayKernelT.hh index 774faf97..07117167 100644 --- a/src/OpenMesh/Tools/Kernel_OSG/ArrayKernelT.hh +++ b/src/OpenMesh/Tools/Kernel_OSG/ArrayKernelT.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= diff --git a/src/OpenMesh/Tools/Kernel_OSG/AttribKernelT.hh b/src/OpenMesh/Tools/Kernel_OSG/AttribKernelT.hh index 6849905e..01b63bd1 100644 --- a/src/OpenMesh/Tools/Kernel_OSG/AttribKernelT.hh +++ b/src/OpenMesh/Tools/Kernel_OSG/AttribKernelT.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef OPENMESH_KERNEL_OSG_ATTRIBKERNEL_HH #define OPENMESH_KENREL_OSG_ATTRIBKERNEL_HH diff --git a/src/OpenMesh/Tools/Kernel_OSG/PropertyKernel.hh b/src/OpenMesh/Tools/Kernel_OSG/PropertyKernel.hh index b2ec6a33..5d58e4e5 100644 --- a/src/OpenMesh/Tools/Kernel_OSG/PropertyKernel.hh +++ b/src/OpenMesh/Tools/Kernel_OSG/PropertyKernel.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef OPENMESH_KERNEL_OSG_PROPERTYKERNEL_HH #define OPENMESH_KENREL_OSG_PROPERTYKERNEL_HH diff --git a/src/OpenMesh/Tools/Kernel_OSG/PropertyT.hh b/src/OpenMesh/Tools/Kernel_OSG/PropertyT.hh index 2530217f..cd0680f9 100644 --- a/src/OpenMesh/Tools/Kernel_OSG/PropertyT.hh +++ b/src/OpenMesh/Tools/Kernel_OSG/PropertyT.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef OPENMESH_KERNEL_OSG_PROPERTYT_HH #define OPENMESH_KERNEL_OSG_PROPERTYT_HH @@ -113,7 +108,7 @@ public: // oPropertyT( const std::string& _name = "" ) - : BaseProperty(_name), data_(NULL) + : BaseProperty(_name), data_(nullptr) { data_ = property_t::create(); diff --git a/src/OpenMesh/Tools/Kernel_OSG/Traits.hh b/src/OpenMesh/Tools/Kernel_OSG/Traits.hh index bc87c01c..73593488 100644 --- a/src/OpenMesh/Tools/Kernel_OSG/Traits.hh +++ b/src/OpenMesh/Tools/Kernel_OSG/Traits.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + /** \file Tools/Kernel_OSG/Traits.hh diff --git a/src/OpenMesh/Tools/Kernel_OSG/TriMesh_OSGArrayKernelT.hh b/src/OpenMesh/Tools/Kernel_OSG/TriMesh_OSGArrayKernelT.hh index ff4bd91d..e0800215 100644 --- a/src/OpenMesh/Tools/Kernel_OSG/TriMesh_OSGArrayKernelT.hh +++ b/src/OpenMesh/Tools/Kernel_OSG/TriMesh_OSGArrayKernelT.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= diff --git a/src/OpenMesh/Tools/Kernel_OSG/VectorAdapter.hh b/src/OpenMesh/Tools/Kernel_OSG/VectorAdapter.hh index bb545d30..dac7b5af 100644 --- a/src/OpenMesh/Tools/Kernel_OSG/VectorAdapter.hh +++ b/src/OpenMesh/Tools/Kernel_OSG/VectorAdapter.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + // ---------------------------------------------------------------------------- diff --git a/src/OpenMesh/Tools/Kernel_OSG/bindT.hh b/src/OpenMesh/Tools/Kernel_OSG/bindT.hh index c93f2c85..bcb859fa 100644 --- a/src/OpenMesh/Tools/Kernel_OSG/bindT.hh +++ b/src/OpenMesh/Tools/Kernel_OSG/bindT.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + /** \file bindT.hh diff --git a/src/OpenMesh/Tools/Kernel_OSG/color_cast.hh b/src/OpenMesh/Tools/Kernel_OSG/color_cast.hh index df4bb3eb..e4f79739 100644 --- a/src/OpenMesh/Tools/Kernel_OSG/color_cast.hh +++ b/src/OpenMesh/Tools/Kernel_OSG/color_cast.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef OPENMESH_KERNEL_OSG_COLOR_CAST_HH #define OPENMESH_KERNEL_OSG_COLOR_CAST_HH diff --git a/src/OpenMesh/Tools/SmartTagger/SmartTaggerT.hh b/src/OpenMesh/Tools/SmartTagger/SmartTaggerT.hh new file mode 100644 index 00000000..77dd65ad --- /dev/null +++ b/src/OpenMesh/Tools/SmartTagger/SmartTaggerT.hh @@ -0,0 +1,241 @@ +/* ========================================================================= * + * * + * OpenMesh * + * Copyright (c) 2001-2015, RWTH-Aachen University * + * Department of Computer Graphics and Multimedia * + * All rights reserved. * + * www.openmesh.org * + * * + *---------------------------------------------------------------------------* + * This file is part of OpenMesh. * + *---------------------------------------------------------------------------* + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * 1. Redistributions of source code must retain the above copyright notice, * + * this list of conditions and the following disclaimer. * + * * + * 2. Redistributions in binary form must reproduce the above copyright * + * notice, this list of conditions and the following disclaimer in the * + * documentation and/or other materials provided with the distribution. * + * * + * 3. Neither the name of the copyright holder nor the names of its * + * contributors may be used to endorse or promote products derived from * + * this software without specific prior written permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER * + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * + * * + * ========================================================================= */ + +#pragma once + + +//== INCLUDES ================================================================= + +// OpenMesh +#include +#include + + +//== DEFINES ================================================================== + +#define STV_DEBUG_CHECKS + +//== NAMESPACES =============================================================== + +namespace OpenMesh { + +//== FORWARD DECLARATIONS ===================================================== + +// Smarttagging for vertices +template< class Mesh> class SmartTaggerVT; +// Smarttagging for edges +template< class Mesh> class SmartTaggerET; +// Smarttagging for faces +template< class Mesh> class SmartTaggerFT; +// Smarttagging for halfedges +template< class Mesh> class SmartTaggerHT; + + +//== CLASS DEFINITION ========================================================= + + +/** \page smarttagger_docu Smart Tagger + +The smart tagger can be used to tag vertices/halfedges/edges/faces on the mesh. It provides +an O(1) reset function to untag all primitives at once. + +Usage: + +\code +SmartTaggerVT< MeshType > tagger(mesh); + +// Reset tagged flag on all vertices +tagger.untag_all(); + +// Check if something is tagged +bool tag = tagger.is_tagged(vh); + +// Set tagged: +tagger.set_tag(vh); +\endcode + +For details see OpenMesh::SmartTaggerT + +*/ + + +/** \brief Smart Tagger + * + * A tagger class to be used on OpenMesh. It provides an O(1) reset function for the property. + * - Smarttagging for vertices: SmartTaggerVT; + * - Smarttagging for edges: SmartTaggerET; + * - Smarttagging for faces: SmartTaggerFT; + * - Smarttagging for halfedges: SmartTaggerHT; + * + * Usage: + * + * \code + * SmartTaggerVT< MeshType >* tagger = new SmartTaggerVT< MeshType > (mesh_); + * + * // Reset tagged flag on all vertices + * tagger.untag_all(); + * + * // Check if something is tagged + * bool tag = tagger.is_tagged(vh); + * + * // Set tagged: + * tagger.set_tag(vh); + * \endcode + */ +template +class SmartTaggerT +{ +public: + + /// Constructor + SmartTaggerT(Mesh& _mesh, unsigned int _tag_range = 1); + + /// Destructor + ~SmartTaggerT(); + + /** \brief untag all elements + * + */ + inline void untag_all(); + + /** \brief untag all elements and set new tag_range + * + * @param _new_tag_range New tag range of the tagger + */ + inline void untag_all( const unsigned int _new_tag_range); + + /** \brief set tag to a value in [0..tag_range] + * + * @param _eh Edge handle for the tag + * @param _tag Tag value + */ + inline void set_tag ( const EHandle _eh, unsigned int _tag = 1); + + /** \brief get tag value in range [0..tag_range] + * + * @param _eh Edge handle for the tag + * @return Current tag value at that edge + */ + inline unsigned int get_tag ( const EHandle _eh) const; + + /** \brief overloaded member for boolean tags + * + * @param _eh Edge handle for the tag + * @return Current tag value at that edge + */ + inline bool is_tagged( const EHandle _eh) const; + + /** \brief set new tag range and untag_all + * + * Set new tag range and reset tagger + * + * @param _tag_range New tag range of the tagger + */ + inline void set_tag_range( const unsigned int _tag_range); + +protected: + + inline void all_tags_to_zero(); + +protected: + + // Reference to Mesh + Mesh& mesh_; + + // property which holds the current tags + EPHandle ep_tag_; + + // current tags range is [current_base_+1...current_base_+tag_range_] + unsigned int current_base_; + + // number of different tagvalues available + unsigned int tag_range_; +}; + + +//== SPECIALIZATION =========================================================== + +// define standard Tagger +template< class Mesh> +class SmartTaggerVT + : public SmartTaggerT< Mesh, typename Mesh::VertexHandle, OpenMesh::VPropHandleT > +{ +public: + typedef SmartTaggerT< Mesh, typename Mesh::VertexHandle, OpenMesh::VPropHandleT > BaseType; + SmartTaggerVT(Mesh& _mesh, unsigned int _tag_range = 1) : BaseType(_mesh, _tag_range) {} +}; + +template< class Mesh> +class SmartTaggerET + : public SmartTaggerT< Mesh, typename Mesh::EdgeHandle, OpenMesh::EPropHandleT > +{ +public: + typedef SmartTaggerT< Mesh, typename Mesh::EdgeHandle, OpenMesh::EPropHandleT > BaseType; + SmartTaggerET(Mesh& _mesh, unsigned int _tag_range = 1) : BaseType(_mesh, _tag_range) {} +}; + +template< class Mesh> +class SmartTaggerFT + : public SmartTaggerT< Mesh, typename Mesh::FaceHandle, OpenMesh::FPropHandleT > +{ +public: + typedef SmartTaggerT< Mesh, typename Mesh::FaceHandle, OpenMesh::FPropHandleT > BaseType; + SmartTaggerFT(Mesh& _mesh, unsigned int _tag_range = 1): BaseType(_mesh, _tag_range) {} +}; + +template< class Mesh> +class SmartTaggerHT + : public SmartTaggerT< Mesh, typename Mesh::HalfedgeHandle, OpenMesh::HPropHandleT > +{ +public: + typedef SmartTaggerT< Mesh, typename Mesh::HalfedgeHandle, OpenMesh::HPropHandleT > BaseType; + SmartTaggerHT(Mesh& _mesh, unsigned int _tag_range = 1): BaseType(_mesh, _tag_range){} +}; + + +//============================================================================= +} // namespace OpenMesh +//============================================================================= +#if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_SMARTTAGGERT_C) +#define OPENMESH_SMARTTAGGERT_TEMPLATES +#include "SmartTaggerT_impl.hh" +#endif + diff --git a/src/OpenMesh/Tools/SmartTagger/SmartTaggerT_impl.hh b/src/OpenMesh/Tools/SmartTagger/SmartTaggerT_impl.hh new file mode 100644 index 00000000..b88330fa --- /dev/null +++ b/src/OpenMesh/Tools/SmartTagger/SmartTaggerT_impl.hh @@ -0,0 +1,205 @@ +/* ========================================================================= * + * * + * OpenMesh * + * Copyright (c) 2001-2015, RWTH-Aachen University * + * Department of Computer Graphics and Multimedia * + * All rights reserved. * + * www.openmesh.org * + * * + *---------------------------------------------------------------------------* + * This file is part of OpenMesh. * + *---------------------------------------------------------------------------* + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * 1. Redistributions of source code must retain the above copyright notice, * + * this list of conditions and the following disclaimer. * + * * + * 2. Redistributions in binary form must reproduce the above copyright * + * notice, this list of conditions and the following disclaimer in the * + * documentation and/or other materials provided with the distribution. * + * * + * 3. Neither the name of the copyright holder nor the names of its * + * contributors may be used to endorse or promote products derived from * + * this software without specific prior written permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER * + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * + * * + * ========================================================================= */ + +#define OPENMESH_SMARTTAGGERT_C + +//== INCLUDES ================================================================= + +#include "SmartTaggerT.hh" + +#include +#include + +//== NAMESPACES =============================================================== + +namespace OpenMesh { + +//== IMPLEMENTATION ========================================================== + +template +SmartTaggerT:: +SmartTaggerT(Mesh& _mesh, unsigned int _tag_range) + : mesh_(_mesh), + current_base_(0), + tag_range_(_tag_range) +{ + // add new property + mesh_.add_property(ep_tag_); + + // reset all tags once + all_tags_to_zero(); +} + + +//----------------------------------------------------------------------------- + + +template +SmartTaggerT:: +~SmartTaggerT() +{ + mesh_.remove_property(ep_tag_); +} + + +//----------------------------------------------------------------------------- + + +template +void +SmartTaggerT:: +untag_all() +{ + unsigned int max_uint = std::numeric_limits::max(); + + if( current_base_ < max_uint - 2*tag_range_) + current_base_ += tag_range_; + else + { + //overflow -> reset all tags +#ifdef STV_DEBUG_CHECKS + std::cerr << "Tagging Overflow occured...\n"; +#endif + current_base_ = 0; + all_tags_to_zero(); + } +} + + +//----------------------------------------------------------------------------- + + +template +void +SmartTaggerT:: +untag_all( const unsigned int _new_tag_range) +{ + set_tag_range(_new_tag_range); +} + + +//----------------------------------------------------------------------------- + +template +void +SmartTaggerT:: +set_tag ( const EHandle _eh, unsigned int _tag) +{ +#ifdef STV_DEBUG_CHECKS + if( _tag > tag_range_) + std::cerr << "ERROR in set_tag tag range!!!\n"; +#endif + + mesh_.property(ep_tag_, _eh) = current_base_ + _tag; +} + + +//----------------------------------------------------------------------------- + + +template +unsigned int +SmartTaggerT:: +get_tag ( const EHandle _eh) const +{ + unsigned int t = mesh_.property(ep_tag_, _eh); + +#ifdef STV_DEBUG_CHECKS + if( t > current_base_ + tag_range_) + std::cerr << "ERROR in get_tag tag range!!!\n"; +#endif + + if( t<= current_base_) return 0; + else return t-current_base_; +} + + +//----------------------------------------------------------------------------- + + +template +bool +SmartTaggerT:: +is_tagged( const EHandle _eh) const +{ + return bool(get_tag(_eh)); +} + + +//----------------------------------------------------------------------------- + + +template +void +SmartTaggerT:: +set_tag_range( const unsigned int _tag_range) +{ + if( _tag_range <= tag_range_) + { + untag_all(); + tag_range_ = _tag_range; + } + else + { + tag_range_ = _tag_range; + untag_all(); + } +} + + +//----------------------------------------------------------------------------- + + +template +void +SmartTaggerT:: +all_tags_to_zero() +{ + // iterate over property vector + for(unsigned int i=0; i(_mesh) {} + explicit JacobiLaplaceSmootherT( Mesh& _mesh ) : LaplaceSmootherT(_mesh) {} // override: alloc umbrellas void smooth(unsigned int _n); @@ -109,7 +104,7 @@ private: //============================================================================= #if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_JACOBI_LAPLACE_SMOOTHERT_C) #define OPENMESH_JACOBI_LAPLACE_SMOOTHERT_TEMPLATES -#include "JacobiLaplaceSmootherT.cc" +#include "JacobiLaplaceSmootherT_impl.hh" #endif //============================================================================= #endif // OPENMESH_JACOBI_LAPLACE_SMOOTHERT_HH defined diff --git a/src/OpenMesh/Tools/Smoother/JacobiLaplaceSmootherT.cc b/src/OpenMesh/Tools/Smoother/JacobiLaplaceSmootherT_impl.hh similarity index 93% rename from src/OpenMesh/Tools/Smoother/JacobiLaplaceSmootherT.cc rename to src/OpenMesh/Tools/Smoother/JacobiLaplaceSmootherT_impl.hh index 62fa98c1..461b85df 100644 --- a/src/OpenMesh/Tools/Smoother/JacobiLaplaceSmootherT.cc +++ b/src/OpenMesh/Tools/Smoother/JacobiLaplaceSmootherT_impl.hh @@ -39,14 +39,9 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ -/** \file JacobiLaplaceSmootherT.cc + +/** \file JacobiLaplaceSmootherT_impl.hh */ @@ -181,7 +176,7 @@ compute_new_positions_C1() if (diag) uu *= static_cast(1.0) / diag; // damping - uu *= static_cast(0.25); + uu *= static_cast::value_type>(0.25); // store new position p = vector_cast(Base::mesh_.point(*v_it)); diff --git a/src/OpenMesh/Tools/Smoother/LaplaceSmootherT.hh b/src/OpenMesh/Tools/Smoother/LaplaceSmootherT.hh index 98dd5f39..c50ec078 100644 --- a/src/OpenMesh/Tools/Smoother/LaplaceSmootherT.hh +++ b/src/OpenMesh/Tools/Smoother/LaplaceSmootherT.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + /** \file LaplaceSmootherT.hh @@ -88,7 +83,7 @@ public: typedef typename SmootherT::EdgeHandle EdgeHandle; - LaplaceSmootherT( Mesh& _mesh ); + explicit LaplaceSmootherT( Mesh& _mesh ); virtual ~LaplaceSmootherT(); @@ -123,7 +118,7 @@ private: //============================================================================= #if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_LAPLACE_SMOOTHERT_C) #define OPENMESH_LAPLACE_SMOOTHERT_TEMPLATES -#include "LaplaceSmootherT.cc" +#include "LaplaceSmootherT_impl.hh" #endif //============================================================================= #endif // OPENMESH_LAPLACE_SMOOTHERT_HH defined diff --git a/src/OpenMesh/Tools/Smoother/LaplaceSmootherT.cc b/src/OpenMesh/Tools/Smoother/LaplaceSmootherT_impl.hh similarity index 91% rename from src/OpenMesh/Tools/Smoother/LaplaceSmootherT.cc rename to src/OpenMesh/Tools/Smoother/LaplaceSmootherT_impl.hh index a9623222..8e53e912 100644 --- a/src/OpenMesh/Tools/Smoother/LaplaceSmootherT.cc +++ b/src/OpenMesh/Tools/Smoother/LaplaceSmootherT_impl.hh @@ -39,14 +39,9 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ -/** \file LaplaceSmootherT.cc + +/** \file LaplaceSmootherT_impl.hh */ @@ -139,7 +134,6 @@ compute_weights(LaplaceWeighting _weighting) typename Mesh::EdgeIter e_it, e_end(Base::mesh_.edges_end()); typename Mesh::HalfedgeHandle heh0, heh1, heh2; typename Mesh::VertexHandle v0, v1; - const typename Mesh::Point *p0, *p1, *p2; typename Mesh::Normal d0, d1; typename Mesh::Scalar weight, lb(-1.0), ub(1.0); @@ -176,7 +170,9 @@ compute_weights(LaplaceWeighting _weighting) case CotWeighting: { for (e_it=Base::mesh_.edges_begin(); e_it!=e_end; ++e_it) - { + { + const typename Mesh::Point *p0, *p1, *p2; + weight = 0.0; heh0 = Base::mesh_.halfedge_handle(*e_it, 0); diff --git a/src/OpenMesh/Tools/Smoother/SmootherT.hh b/src/OpenMesh/Tools/Smoother/SmootherT.hh index 65d37643..90714768 100644 --- a/src/OpenMesh/Tools/Smoother/SmootherT.hh +++ b/src/OpenMesh/Tools/Smoother/SmootherT.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + /** \file SmootherT.hh @@ -252,7 +247,7 @@ private: //============================================================================= #if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_SMOOTHERT_C) #define OPENMESH_SMOOTHERT_TEMPLATES -#include "SmootherT.cc" +#include "SmootherT_impl.hh" #endif //============================================================================= #endif // OPENMESH_SMOOTHER_SMOOTHERT_HH defined diff --git a/src/OpenMesh/Tools/Smoother/SmootherT.cc b/src/OpenMesh/Tools/Smoother/SmootherT_impl.hh similarity index 95% rename from src/OpenMesh/Tools/Smoother/SmootherT.cc rename to src/OpenMesh/Tools/Smoother/SmootherT_impl.hh index 2bb44bd0..b9bee5c5 100644 --- a/src/OpenMesh/Tools/Smoother/SmootherT.cc +++ b/src/OpenMesh/Tools/Smoother/SmootherT_impl.hh @@ -39,14 +39,9 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ -/** \file SmootherT.cc + +/** \file SmootherT_impl.hh */ @@ -263,13 +258,13 @@ set_relative_local_error(Scalar _err) bb_min = bb_max = mesh_.point(*v_it); for (++v_it; v_it!=v_end; ++v_it) { - bb_min.minimize(mesh_.point(*v_it)); - bb_max.maximize(mesh_.point(*v_it)); + minimize(bb_min, mesh_.point(*v_it)); + maximize(bb_max, mesh_.point(*v_it)); } // abs. error = rel. error * bounding-diagonal - set_absolute_local_error(_err * (bb_max-bb_min).norm()); + set_absolute_local_error(norm(_err * (bb_max-bb_min))); } } diff --git a/src/OpenMesh/Tools/Smoother/smooth_mesh.hh b/src/OpenMesh/Tools/Smoother/smooth_mesh.hh index fad9d67a..51a0fc4d 100644 --- a/src/OpenMesh/Tools/Smoother/smooth_mesh.hh +++ b/src/OpenMesh/Tools/Smoother/smooth_mesh.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef SMOOTH_MESH_HH #define SMOOTH_MESH_HH diff --git a/src/OpenMesh/Tools/Subdivider/Adaptive/Composite/CompositeT.hh b/src/OpenMesh/Tools/Subdivider/Adaptive/Composite/CompositeT.hh index c6bb4b00..b9298263 100644 --- a/src/OpenMesh/Tools/Subdivider/Adaptive/Composite/CompositeT.hh +++ b/src/OpenMesh/Tools/Subdivider/Adaptive/Composite/CompositeT.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + /** \file Adaptive/Composite/CompositeT.hh @@ -151,9 +146,9 @@ public: public: /// Constructor - CompositeT(Mesh& _mesh) + explicit CompositeT(Mesh& _mesh) : subdiv_type_(0), - subdiv_rule_(NULL), /*first_rule_(NULL), last_rule_(NULL),*/ mesh_(_mesh) + subdiv_rule_(nullptr), /*first_rule_(nullptr), last_rule_(nullptr),*/ mesh_(_mesh) { } /// @@ -166,7 +161,7 @@ public: void cleanup(void) { subdiv_type_ = 0; - subdiv_rule_ = NULL; + subdiv_rule_ = nullptr; std::for_each(rule_sequence_.begin(), rule_sequence_.end(), DeleteRule() ); @@ -261,15 +256,15 @@ protected: protected: // helper // get current generation from state - state_t generation(state_t _s) { return _s-(_s % n_rules()); } - state_t generation( VH _vh ) { return generation(mesh_.data(_vh).state()); } - state_t generation( EH _eh ) { return generation(mesh_.data(_eh).state()); } - state_t generation( FH _fh ) { return generation(mesh_.data(_fh).state()); } + state_t generation(state_t _s) const { return _s-(_s % n_rules()); } + state_t generation( VH _vh ) const { return generation(mesh_.data(_vh).state()); } + state_t generation( EH _eh ) const { return generation(mesh_.data(_eh).state()); } + state_t generation( FH _fh ) const { return generation(mesh_.data(_fh).state()); } private: // short cuts - Rule* t_rule() { return subdiv_rule_; } + Rule* t_rule() const { return subdiv_rule_; } Rule* f_rule() { return rule_sequence_.front(); } Rule* l_rule() { return rule_sequence_.back(); } @@ -309,7 +304,7 @@ private: //============================================================================= #if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_SUBDIVIDER_ADAPTIVE_COMPOSITET_CC) # define OPENMESH_SUBDIVIDER_TEMPLATES -# include "CompositeT.cc" +# include "CompositeT_impl.hh" #endif //============================================================================= #endif // OPENMESH_SUBDIVIDER_ADAPTIVE_COMPOSITET_HH defined diff --git a/src/OpenMesh/Tools/Subdivider/Adaptive/Composite/CompositeT.cc b/src/OpenMesh/Tools/Subdivider/Adaptive/Composite/CompositeT_impl.hh similarity index 95% rename from src/OpenMesh/Tools/Subdivider/Adaptive/Composite/CompositeT.cc rename to src/OpenMesh/Tools/Subdivider/Adaptive/Composite/CompositeT_impl.hh index 049f5680..e13bb0a4 100644 --- a/src/OpenMesh/Tools/Subdivider/Adaptive/Composite/CompositeT.cc +++ b/src/OpenMesh/Tools/Subdivider/Adaptive/Composite/CompositeT_impl.hh @@ -39,14 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ - -/** \file Adaptive/Composite/CompositeT.cc +/** \file Adaptive/Composite/CompositeT_impl.hh */ diff --git a/src/OpenMesh/Tools/Subdivider/Adaptive/Composite/CompositeTraits.hh b/src/OpenMesh/Tools/Subdivider/Adaptive/Composite/CompositeTraits.hh index d930d064..8418177d 100644 --- a/src/OpenMesh/Tools/Subdivider/Adaptive/Composite/CompositeTraits.hh +++ b/src/OpenMesh/Tools/Subdivider/Adaptive/Composite/CompositeTraits.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + /** \file Subdivider/Adaptive/Composite/CompositeTraits.hh Mesh traits for adaptive composite subdivider. diff --git a/src/OpenMesh/Tools/Subdivider/Adaptive/Composite/RuleInterfaceT.hh b/src/OpenMesh/Tools/Subdivider/Adaptive/Composite/RuleInterfaceT.hh index 33046b5c..dc133148 100644 --- a/src/OpenMesh/Tools/Subdivider/Adaptive/Composite/RuleInterfaceT.hh +++ b/src/OpenMesh/Tools/Subdivider/Adaptive/Composite/RuleInterfaceT.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= @@ -101,7 +96,7 @@ struct RuleHandleT : public BaseHandle protected:\ friend class CompositeT; \ public: \ - const char *type() const { return #classname; } \ + const char *type() const override { return #classname; } \ typedef classname Self; \ typedef RuleHandleT< Self > Handle @@ -123,7 +118,7 @@ public: protected: /// Default constructor - RuleInterfaceT(Mesh& _mesh) : mesh_(_mesh) {}; + RuleInterfaceT(Mesh& _mesh) : mesh_(_mesh),prev_rule_(nullptr),subdiv_rule_(nullptr),subdiv_type_(0),number_(0),n_rules_(0) {}; public: @@ -363,12 +358,12 @@ protected: Self* prev_rule() { return prev_rule_; } void set_subdiv_rule(Self*& _n) { subdiv_rule_ = _n; } - Self* subdiv_rule() { return subdiv_rule_; } + Self* subdiv_rule() const { return subdiv_rule_; } void set_number(int _n) { number_ = _n; } void set_n_rules(int _n) { n_rules_ = _n; } - int n_rules() { return n_rules_; } + int n_rules() const { return n_rules_; } void set_subdiv_type(int _n) { assert(_n == 3 || _n == 4); subdiv_type_ = _n; } diff --git a/src/OpenMesh/Tools/Subdivider/Adaptive/Composite/RulesT.hh b/src/OpenMesh/Tools/Subdivider/Adaptive/Composite/RulesT.hh index 6068ac5c..2c2e7679 100644 --- a/src/OpenMesh/Tools/Subdivider/Adaptive/Composite/RulesT.hh +++ b/src/OpenMesh/Tools/Subdivider/Adaptive/Composite/RulesT.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + /** \file RulesT.hh @@ -104,10 +99,10 @@ public: typedef RuleInterfaceT Inherited; - Tvv3(M& _mesh) : Inherited(_mesh) { Base::set_subdiv_type(3); }; + explicit Tvv3(M& _mesh) : Inherited(_mesh) { Base::set_subdiv_type(3); }; - void raise(typename M::FaceHandle& _fh, state_t _target_state); - void raise(typename M::VertexHandle& _vh, state_t _target_state); + void raise(typename M::FaceHandle& _fh, state_t _target_state) override; + void raise(typename M::VertexHandle& _vh, state_t _target_state) override; MIPS_WARN_WA(Edge) // avoid warning }; @@ -129,11 +124,11 @@ public: typedef RuleInterfaceT Inherited; - Tvv4(M& _mesh) : Inherited(_mesh) { Base::set_subdiv_type(4); }; + explicit Tvv4(M& _mesh) : Inherited(_mesh) { Base::set_subdiv_type(4); }; - void raise(typename M::FaceHandle& _fh, state_t _target_state); - void raise(typename M::VertexHandle& _vh, state_t _target_state); - void raise(typename M::EdgeHandle& _eh, state_t _target_state); + void raise(typename M::FaceHandle& _fh, state_t _target_state) override; + void raise(typename M::VertexHandle& _vh, state_t _target_state) override; + void raise(typename M::EdgeHandle& _eh, state_t _target_state) override; private: @@ -157,9 +152,9 @@ private: public: typedef RuleInterfaceT Inherited; - VF(M& _mesh) : Inherited(_mesh) {} + explicit VF(M& _mesh) : Inherited(_mesh) {} - void raise(typename M::FaceHandle& _fh, state_t _target_state); + void raise(typename M::FaceHandle& _fh, state_t _target_state) override; MIPS_WARN_WA(Edge) MIPS_WARN_WA(Vertex) }; @@ -179,9 +174,9 @@ private: public: typedef RuleInterfaceT Inherited; - FF(M& _mesh) : Inherited(_mesh) {} + explicit FF(M& _mesh) : Inherited(_mesh) {} - void raise(typename M::FaceHandle& _fh, state_t _target_state); + void raise(typename M::FaceHandle& _fh, state_t _target_state) override; MIPS_WARN_WA(Vertex) // avoid warning MIPS_WARN_WA(Edge ) // avoid warning }; @@ -201,9 +196,9 @@ private: public: typedef RuleInterfaceT Inherited; - FFc(M& _mesh) : Inherited(_mesh) {} + explicit FFc(M& _mesh) : Inherited(_mesh) {} - void raise(typename M::FaceHandle& _fh, state_t _target_state); + void raise(typename M::FaceHandle& _fh, state_t _target_state) override; MIPS_WARN_WA(Vertex) // avoid warning MIPS_WARN_WA(Edge ) // avoid warning }; @@ -223,9 +218,9 @@ private: public: typedef RuleInterfaceT Inherited; - FV(M& _mesh) : Inherited(_mesh) {} + explicit FV(M& _mesh) : Inherited(_mesh) {} - void raise(typename M::VertexHandle& _vh, state_t _target_state); + void raise(typename M::VertexHandle& _vh, state_t _target_state) override; MIPS_WARN_WA(Face) // avoid warning MIPS_WARN_WA(Edge) // avoid warning }; @@ -245,9 +240,9 @@ private: public: typedef RuleInterfaceT Inherited; - FVc(M& _mesh) : Inherited(_mesh) { init_coeffs(50); } + explicit FVc(M& _mesh) : Inherited(_mesh) { init_coeffs(50); } - void raise(typename M::VertexHandle& _vh, state_t _target_state); + void raise(typename M::VertexHandle& _vh, state_t _target_state) override; MIPS_WARN_WA(Face) // avoid warning MIPS_WARN_WA(Edge) // avoid warning @@ -282,9 +277,9 @@ public: typedef RuleInterfaceT Inherited; - VV(M& _mesh) : Inherited(_mesh) {} + explicit VV(M& _mesh) : Inherited(_mesh) {} - void raise(typename M::VertexHandle& _vh, state_t _target_state); + void raise(typename M::VertexHandle& _vh, state_t _target_state) override; MIPS_WARN_WA(Face) // avoid warning MIPS_WARN_WA(Edge) // avoid warning }; @@ -304,9 +299,9 @@ private: public: typedef RuleInterfaceT Inherited; - VVc(M& _mesh) : Inherited(_mesh) {} + explicit VVc(M& _mesh) : Inherited(_mesh) {} - void raise(typename M::VertexHandle& _vh, state_t _target_state); + void raise(typename M::VertexHandle& _vh, state_t _target_state) override; MIPS_WARN_WA(Face) // avoid warning MIPS_WARN_WA(Edge) // avoid warning }; @@ -326,9 +321,9 @@ private: public: typedef RuleInterfaceT Inherited; - VE(M& _mesh) : Inherited(_mesh) {} + explicit VE(M& _mesh) : Inherited(_mesh) {} - void raise(typename M::EdgeHandle& _eh, state_t _target_state); + void raise(typename M::EdgeHandle& _eh, state_t _target_state) override; MIPS_WARN_WA(Face ) // avoid warning MIPS_WARN_WA(Vertex) // avoid warning }; @@ -348,9 +343,9 @@ private: public: typedef RuleInterfaceT Inherited; - VdE(M& _mesh) : Inherited(_mesh) {} + explicit VdE(M& _mesh) : Inherited(_mesh) {} - void raise(typename M::EdgeHandle& _eh, state_t _target_state); + void raise(typename M::EdgeHandle& _eh, state_t _target_state) override; MIPS_WARN_WA(Face ) // avoid warning MIPS_WARN_WA(Vertex) // avoid warning }; @@ -370,9 +365,9 @@ private: public: typedef RuleInterfaceT Inherited; - VdEc(M& _mesh) : Inherited(_mesh) {} + explicit VdEc(M& _mesh) : Inherited(_mesh) {} - void raise(typename M::EdgeHandle& _eh, state_t _target_state); + void raise(typename M::EdgeHandle& _eh, state_t _target_state) override; MIPS_WARN_WA(Face ) // avoid warning MIPS_WARN_WA(Vertex) // avoid warning }; @@ -392,9 +387,9 @@ private: public: typedef RuleInterfaceT Inherited; - EV(M& _mesh) : Inherited(_mesh) {} + explicit EV(M& _mesh) : Inherited(_mesh) {} - void raise(typename M::VertexHandle& _vh, state_t _target_state); + void raise(typename M::VertexHandle& _vh, state_t _target_state) override; MIPS_WARN_WA(Face) // avoid warning MIPS_WARN_WA(Edge) // avoid warning }; @@ -415,9 +410,9 @@ public: typedef RuleInterfaceT Inherited; - EVc(M& _mesh) : Inherited(_mesh) { init_coeffs(50); } + explicit EVc(M& _mesh) : Inherited(_mesh) { init_coeffs(50); } - void raise(typename M::VertexHandle& _vh, state_t _target_state); + void raise(typename M::VertexHandle& _vh, state_t _target_state) override; MIPS_WARN_WA(Face) // avoid warning MIPS_WARN_WA(Edge) // avoid warning @@ -451,9 +446,9 @@ private: public: typedef RuleInterfaceT Inherited; - EF(M& _mesh) : Inherited(_mesh) {} + explicit EF(M& _mesh) : Inherited(_mesh) {} - void raise(typename M::FaceHandle& _fh, state_t _target_state); + void raise(typename M::FaceHandle& _fh, state_t _target_state) override; MIPS_WARN_WA(Edge ) // avoid warning MIPS_WARN_WA(Vertex) // avoid warning }; @@ -473,9 +468,9 @@ private: public: typedef RuleInterfaceT Inherited; - FE(M& _mesh) : Inherited(_mesh) {} + explicit FE(M& _mesh) : Inherited(_mesh) {} - void raise(typename M::EdgeHandle& _eh, state_t _target_state); + void raise(typename M::EdgeHandle& _eh, state_t _target_state) override; MIPS_WARN_WA(Face ) // avoid warning MIPS_WARN_WA(Vertex) // avoid warning }; @@ -495,9 +490,9 @@ private: public: typedef RuleInterfaceT Inherited; - EdE(M& _mesh) : Inherited(_mesh) {} + explicit EdE(M& _mesh) : Inherited(_mesh) {} - void raise(typename M::EdgeHandle& _eh, state_t _target_state); + void raise(typename M::EdgeHandle& _eh, state_t _target_state) override; MIPS_WARN_WA(Face ) // avoid warning MIPS_WARN_WA(Vertex) // avoid warning }; @@ -517,9 +512,9 @@ private: public: typedef RuleInterfaceT Inherited; - EdEc(M& _mesh) : Inherited(_mesh) {} + explicit EdEc(M& _mesh) : Inherited(_mesh) {} - void raise(typename M::EdgeHandle& _eh, state_t _target_state); + void raise(typename M::EdgeHandle& _eh, state_t _target_state) override; MIPS_WARN_WA(Face ) // avoid warning MIPS_WARN_WA(Vertex) // avoid warning }; @@ -535,7 +530,7 @@ public: //============================================================================= #if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_SUBDIVIDER_ADAPTIVE_RULEST_CC) # define OPENMESH_SUBDIVIDER_TEMPLATES -# include "RulesT.cc" +# include "RulesT_impl.hh" #endif //============================================================================= #endif // OPENMESH_SUBDIVIDER_ADAPTIVE_RULEST_HH defined diff --git a/src/OpenMesh/Tools/Subdivider/Adaptive/Composite/RulesT.cc b/src/OpenMesh/Tools/Subdivider/Adaptive/Composite/RulesT_impl.hh similarity index 99% rename from src/OpenMesh/Tools/Subdivider/Adaptive/Composite/RulesT.cc rename to src/OpenMesh/Tools/Subdivider/Adaptive/Composite/RulesT_impl.hh index 1213cab7..8de1456e 100644 --- a/src/OpenMesh/Tools/Subdivider/Adaptive/Composite/RulesT.cc +++ b/src/OpenMesh/Tools/Subdivider/Adaptive/Composite/RulesT_impl.hh @@ -39,14 +39,9 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ -/** \file RulesT.cc + +/** \file RulesT_impl.hh */ diff --git a/src/OpenMesh/Tools/Subdivider/Adaptive/Composite/Traits.hh b/src/OpenMesh/Tools/Subdivider/Adaptive/Composite/Traits.hh index a915c1fa..06addf8a 100644 --- a/src/OpenMesh/Tools/Subdivider/Adaptive/Composite/Traits.hh +++ b/src/OpenMesh/Tools/Subdivider/Adaptive/Composite/Traits.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + /** \file Composite/Traits.hh diff --git a/src/OpenMesh/Tools/Subdivider/Uniform/CatmullClarkT.hh b/src/OpenMesh/Tools/Subdivider/Uniform/CatmullClarkT.hh index c756a0fa..a1d71f97 100644 --- a/src/OpenMesh/Tools/Subdivider/Uniform/CatmullClarkT.hh +++ b/src/OpenMesh/Tools/Subdivider/Uniform/CatmullClarkT.hh @@ -39,13 +39,6 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision: 520 $ * - * $Date: 2012-01-20 15:29:31 +0100 (Fr, 20 Jan 2012) $ * - * * -\*===========================================================================*/ - /** \file CatmullClarkT.hh */ @@ -121,15 +114,15 @@ public: public: - const char *name() const { return "Uniform CatmullClark"; } + const char *name() const override { return "Uniform CatmullClark"; } protected: /// Initialize properties and weights - virtual bool prepare( MeshType& _m ); + virtual bool prepare( MeshType& _m ) override; /// Remove properties and weights - virtual bool cleanup( MeshType& _m ); + virtual bool cleanup( MeshType& _m ) override; /** \brief Execute n subdivision steps * @@ -138,7 +131,7 @@ protected: * @param _update_points Unused here * @return successful? */ - virtual bool subdivide( MeshType& _m, size_t _n , const bool _update_points = true); + virtual bool subdivide( MeshType& _m, size_t _n , const bool _update_points = true) override; private: @@ -174,7 +167,7 @@ private: //============================================================================= #if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_SUBDIVIDER_UNIFORM_CATMULLCLARK_CC) # define OPENMESH_SUBDIVIDER_TEMPLATES -# include "CatmullClarkT.cc" +# include "CatmullClarkT_impl.hh" #endif //============================================================================= #endif // OPENMESH_SUBDIVIDER_UNIFORM_CATMULLCLARKT_HH defined diff --git a/src/OpenMesh/Tools/Subdivider/Uniform/CatmullClarkT.cc b/src/OpenMesh/Tools/Subdivider/Uniform/CatmullClarkT_impl.hh similarity index 89% rename from src/OpenMesh/Tools/Subdivider/Uniform/CatmullClarkT.cc rename to src/OpenMesh/Tools/Subdivider/Uniform/CatmullClarkT_impl.hh index 712ddb51..e74e99a7 100644 --- a/src/OpenMesh/Tools/Subdivider/Uniform/CatmullClarkT.cc +++ b/src/OpenMesh/Tools/Subdivider/Uniform/CatmullClarkT_impl.hh @@ -39,13 +39,6 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision: 520 $ * - * $Date: 2012-01-20 15:29:31 +0100 (Fr, 20 Jan 2012) $ * - * * -\*===========================================================================*/ - //============================================================================= // // CLASS CatmullClarkT - IMPLEMENTATION @@ -107,47 +100,38 @@ CatmullClarkT::subdivide( MeshType& _m , size_t _n , const bo { // Compute face centroid - FaceIter f_itr = _m.faces_begin(); - FaceIter f_end = _m.faces_end(); - for ( ; f_itr != f_end; ++f_itr) + for ( auto fh : _m.faces()) { Point centroid; - _m.calc_face_centroid( *f_itr, centroid); - _m.property( fp_pos_, *f_itr ) = centroid; + _m.calc_face_centroid( fh, centroid); + _m.property( fp_pos_, fh ) = centroid; } // Compute position for new (edge-) vertices and store them in the edge property - EdgeIter e_itr = _m.edges_begin(); - EdgeIter e_end = _m.edges_end(); - for ( ; e_itr != e_end; ++e_itr) - compute_midpoint( _m, *e_itr, _update_points ); + for ( auto eh : _m.edges()) + compute_midpoint( _m, eh, _update_points ); // position updates activated? if(_update_points) { // compute new positions for old vertices - VertexIter v_itr = _m.vertices_begin(); - VertexIter v_end = _m.vertices_end(); - for ( ; v_itr != v_end; ++v_itr) - update_vertex( _m, *v_itr ); + for ( auto vh : _m.vertices()) + update_vertex( _m, vh ); // Commit changes in geometry - v_itr = _m.vertices_begin(); - for ( ; v_itr != v_end; ++v_itr) - _m.set_point(*v_itr, _m.property( vp_pos_, *v_itr ) ); + for ( auto vh : _m.vertices()) + _m.set_point(vh, _m.property( vp_pos_, vh ) ); } // Split each edge at midpoint stored in edge property ep_pos_; // Attention! Creating new edges, hence make sure the loop ends correctly. - e_itr = _m.edges_begin(); - for ( ; e_itr != e_end; ++e_itr) - split_edge( _m, *e_itr ); + for ( auto eh : _m.edges()) + split_edge( _m, eh ); // Commit changes in topology and reconsitute consistency // Attention! Creating new faces, hence make sure the loop ends correctly. - f_itr = _m.faces_begin(); - for ( ; f_itr != f_end; ++f_itr) - split_face( _m, *f_itr); + for ( auto fh : _m.faces()) + split_face( _m, fh); #if defined(_DEBUG) || defined(DEBUG) @@ -340,13 +324,12 @@ CatmullClarkT::update_vertex( MeshType& _m, const VertexHandl // and http://www.cs.utah.edu/~lacewell/subdeval if ( _m.is_boundary( _vh)) { - Normal Vec; pos = _m.point(_vh); VertexEdgeIter ve_itr; for ( ve_itr = _m.ve_iter( _vh); ve_itr.is_valid(); ++ve_itr) if ( _m.is_boundary( *ve_itr)) pos += _m.property( ep_pos_, *ve_itr); - pos /= static_cast(3.0); + pos /= static_cast::value_type>(3.0); } else // inner vertex { diff --git a/src/OpenMesh/Tools/Subdivider/Uniform/Composite/CompositeT.hh b/src/OpenMesh/Tools/Subdivider/Uniform/Composite/CompositeT.hh index 6566d0a9..6a9b2fb0 100644 --- a/src/OpenMesh/Tools/Subdivider/Uniform/Composite/CompositeT.hh +++ b/src/OpenMesh/Tools/Subdivider/Uniform/Composite/CompositeT.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + /** \file Uniform/Composite/CompositeT.hh @@ -101,19 +96,19 @@ public: public: - CompositeT(void) : parent_t(), p_mesh_(NULL) {} - explicit CompositeT(MeshType& _mesh) : parent_t(_mesh), p_mesh_(NULL) {}; + CompositeT(void) : parent_t(), p_mesh_(nullptr) {} + explicit CompositeT(MeshType& _mesh) : parent_t(_mesh), p_mesh_(nullptr) {}; virtual ~CompositeT() { } public: // inherited interface - virtual const char *name( void ) const = 0; + virtual const char *name( void ) const override = 0; protected: // inherited interface - bool prepare( MeshType& _m ); + bool prepare( MeshType& _m ) override; - bool subdivide( MeshType& _m, size_t _n, const bool _update_points = true ) + bool subdivide( MeshType& _m, size_t _n, const bool _update_points = true ) override { assert( p_mesh_ == &_m ); @@ -127,13 +122,13 @@ protected: // inherited interface } #ifdef NDEBUG - bool cleanup( MeshType& ) + bool cleanup( MeshType& ) override #else - bool cleanup( MeshType& _m ) + bool cleanup( MeshType& _m ) override #endif { assert( p_mesh_ == &_m ); - p_mesh_=NULL; + p_mesh_=nullptr; return true; } @@ -243,7 +238,7 @@ private: //============================================================================= #if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_SUBDIVIDER_UNIFORM_COMPOSITE_CC) #define OPENMESH_SUBDIVIDER_TEMPLATES -#include "CompositeT.cc" +#include "CompositeT_impl.hh" #endif //============================================================================= #endif // COMPOSITET_HH defined diff --git a/src/OpenMesh/Tools/Subdivider/Uniform/Composite/CompositeT.cc b/src/OpenMesh/Tools/Subdivider/Uniform/Composite/CompositeT_impl.hh similarity index 98% rename from src/OpenMesh/Tools/Subdivider/Uniform/Composite/CompositeT.cc rename to src/OpenMesh/Tools/Subdivider/Uniform/Composite/CompositeT_impl.hh index 621d3b9c..c9518ef0 100644 --- a/src/OpenMesh/Tools/Subdivider/Uniform/Composite/CompositeT.cc +++ b/src/OpenMesh/Tools/Subdivider/Uniform/Composite/CompositeT_impl.hh @@ -39,14 +39,9 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ -/** \file Uniform/Composite/CompositeT.cc + +/** \file Uniform/Composite/CompositeT_impl.hh */ @@ -581,7 +576,7 @@ void CompositeT::FVc(Coeff& _coeff) ++valence; } - c = static_cast(_coeff(valence)); + c = static_cast(_coeff(valence)); for (voh_it = mesh_.voh_iter(*v_it); voh_it.is_valid(); ++voh_it) { diff --git a/src/OpenMesh/Tools/Subdivider/Uniform/Composite/CompositeTraits.hh b/src/OpenMesh/Tools/Subdivider/Uniform/Composite/CompositeTraits.hh index 0ba352f5..9a90362d 100644 --- a/src/OpenMesh/Tools/Subdivider/Uniform/Composite/CompositeTraits.hh +++ b/src/OpenMesh/Tools/Subdivider/Uniform/Composite/CompositeTraits.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + /** \file Uniform/Composite/CompositeTraits.hh Mesh traits for uniform composite subdivision. @@ -91,6 +86,7 @@ struct CompositeTraits : public OpenMesh::DefaultTraits FaceTraits { + private: typedef typename Refs::HalfedgeHandle HalfedgeHandle; typedef typename Refs::Scalar Scalar; diff --git a/src/OpenMesh/Tools/Subdivider/Uniform/CompositeLoopT.hh b/src/OpenMesh/Tools/Subdivider/Uniform/CompositeLoopT.hh index ad2f3bf7..f8266fd2 100644 --- a/src/OpenMesh/Tools/Subdivider/Uniform/CompositeLoopT.hh +++ b/src/OpenMesh/Tools/Subdivider/Uniform/CompositeLoopT.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + /** \file CompositeLoopT.hh @@ -87,16 +82,16 @@ public: public: CompositeLoopT() : Inherited() {}; - CompositeLoopT(MeshType& _mesh) : Inherited(_mesh) {}; + explicit CompositeLoopT(MeshType& _mesh) : Inherited(_mesh) {}; ~CompositeLoopT() {} public: - const char *name() const { return "Uniform Composite Loop"; } + const char *name() const override { return "Uniform Composite Loop"; } protected: // inherited interface - void apply_rules(void) + void apply_rules(void) override { Inherited::Tvv4(); Inherited::VdE(); @@ -124,7 +119,7 @@ protected: weights_.end(), compute_weight() ); } - double operator()(size_t _valence) { return weights_[_valence]; } + double operator()(size_t _valence) override { return weights_[_valence]; } /// \internal struct compute_weight diff --git a/src/OpenMesh/Tools/Subdivider/Uniform/CompositeSqrt3T.hh b/src/OpenMesh/Tools/Subdivider/Uniform/CompositeSqrt3T.hh index 28705938..bcc72002 100644 --- a/src/OpenMesh/Tools/Subdivider/Uniform/CompositeSqrt3T.hh +++ b/src/OpenMesh/Tools/Subdivider/Uniform/CompositeSqrt3T.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + /** \file CompositeSqrt3T.hh @@ -87,16 +82,16 @@ public: public: CompositeSqrt3T() : Inherited() {}; - CompositeSqrt3T(MeshType& _mesh) : Inherited(_mesh) {}; + explicit CompositeSqrt3T(MeshType& _mesh) : Inherited(_mesh) {}; ~CompositeSqrt3T() {} public: - const char *name() const { return "Uniform Composite Sqrt3"; } + const char *name() const override { return "Uniform Composite Sqrt3"; } protected: // inherited interface - void apply_rules(void) + void apply_rules(void) override { Inherited::Tvv3(); Inherited::VF(); @@ -122,7 +117,7 @@ protected: weights_.end(), compute_weight() ); } - double operator()(size_t _valence) { return weights_[_valence]; } + double operator()(size_t _valence) override { return weights_[_valence]; } /** \internal */ diff --git a/src/OpenMesh/Tools/Subdivider/Uniform/LongestEdgeT.hh b/src/OpenMesh/Tools/Subdivider/Uniform/LongestEdgeT.hh index c689af3f..3690695a 100644 --- a/src/OpenMesh/Tools/Subdivider/Uniform/LongestEdgeT.hh +++ b/src/OpenMesh/Tools/Subdivider/Uniform/LongestEdgeT.hh @@ -39,12 +39,6 @@ * * * ========================================================================= */ -/*==========================================================================*\ -* * -* $Revision: 410 $ * -* $Date: 2010-06-17 12:45:58 +0200 (Do, 17. Jun 2010) $ * -* * -\*==========================================================================*/ /** \file LongestEdgeT.hh diff --git a/src/OpenMesh/Tools/Subdivider/Uniform/LoopT.hh b/src/OpenMesh/Tools/Subdivider/Uniform/LoopT.hh index 7701b000..4601367c 100644 --- a/src/OpenMesh/Tools/Subdivider/Uniform/LoopT.hh +++ b/src/OpenMesh/Tools/Subdivider/Uniform/LoopT.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + /** \file LoopT.hh @@ -111,7 +106,7 @@ public: { init_weights(); } - LoopT( mesh_t& _m ) : parent_t(_m), _1over8( 1.0/8.0 ), _3over8( 3.0/8.0 ) + explicit LoopT( mesh_t& _m ) : parent_t(_m), _1over8( 1.0/8.0 ), _3over8( 3.0/8.0 ) { init_weights(); } @@ -121,7 +116,7 @@ public: public: - const char *name() const { return "Uniform Loop"; } + const char *name() const override { return "Uniform Loop"; } /// Pre-compute weights @@ -135,7 +130,7 @@ public: protected: - bool prepare( mesh_t& _m ) + bool prepare( mesh_t& _m ) override { _m.add_property( vp_pos_ ); _m.add_property( ep_pos_ ); @@ -143,7 +138,7 @@ protected: } - bool cleanup( mesh_t& _m ) + bool cleanup( mesh_t& _m ) override { _m.remove_property( vp_pos_ ); _m.remove_property( ep_pos_ ); @@ -151,7 +146,7 @@ protected: } - bool subdivide( mesh_t& _m, size_t _n, const bool _update_points = true) + bool subdivide( mesh_t& _m, size_t _n, const bool _update_points = true) override { ///TODO:Implement fixed positions @@ -179,17 +174,15 @@ protected: // edge property ep_pos_) in the vertex property vp_pos_; // Attention! Creating new edges, hence make sure the loop ends correctly. - e_end = _m.edges_end(); - for (eit=_m.edges_begin(); eit != e_end; ++eit) - split_edge(_m, *eit ); + for (auto eh : _m.edges()) + split_edge(_m, eh ); // Commit changes in topology and reconsitute consistency // Attention! Creating new faces, hence make sure the loop ends correctly. - f_end = _m.faces_end(); - for (fit = _m.faces_begin(); fit != f_end; ++fit) - split_face(_m, *fit ); + for (auto fh : _m.faces()) + split_face(_m, fh ); if(_update_points) { // Commit changes in geometry @@ -326,7 +319,7 @@ private: // topological modifiers typename mesh_t::VertexHandle vh1(_m.to_vertex_handle(heh)); typename mesh_t::Point midP(_m.point(_m.to_vertex_handle(heh))); midP += _m.point(_m.to_vertex_handle(opp_heh)); - midP *= static_cast(0.5); + midP *= static_cast(0.5); // new vertex vh = _m.new_vertex( midP ); @@ -368,7 +361,11 @@ private: // topological modifiers _m.set_face_handle( new_heh, _m.face_handle(heh) ); _m.set_halfedge_handle( vh, new_heh); - _m.set_halfedge_handle( _m.face_handle(heh), heh ); + + // We cant reconnect a non existing face, so we skip this here if necessary + if ( !_m.is_boundary(heh) ) + _m.set_halfedge_handle( _m.face_handle(heh), heh ); + _m.set_halfedge_handle( vh1, opp_new_heh ); // Never forget this, when playing with the topology @@ -394,7 +391,7 @@ private: // geometry helper // boundary edge: just average vertex positions if (_m.is_boundary(_eh) ) { - pos *= static_cast(0.5); + pos *= static_cast(0.5); } else // inner edge: add neighbouring Vertices to sum { diff --git a/src/OpenMesh/Tools/Subdivider/Uniform/MidpointT.hh b/src/OpenMesh/Tools/Subdivider/Uniform/MidpointT.hh index 3014449c..f92e2a43 100644 --- a/src/OpenMesh/Tools/Subdivider/Uniform/MidpointT.hh +++ b/src/OpenMesh/Tools/Subdivider/Uniform/MidpointT.hh @@ -51,49 +51,39 @@ protected: // SubdividerT interface _m.request_edge_status(); _m.request_vertex_status(); _m.request_face_status(); - PropertyManager, mesh_t> edge_midpoint(_m, "edge_midpoint"); - PropertyManager, mesh_t> is_original_vertex(_m, "is_original_vertex"); + PropertyManager> edge_midpoint(_m, "edge_midpoint"); + PropertyManager> is_original_vertex(_m, "is_original_vertex"); for (size_t iteration = 0; iteration < _n; ++iteration) { is_original_vertex.set_range(_m.vertices_begin(), _m.vertices_end(), true); // Create vertices on edge midpoints - for (typename mesh_t::EdgeIter it = _m.edges_begin(), end = _m.edges_end(); it != end; ++it) { - EdgeHandle eh = *it; + for (auto eh : _m.edges()) { VertexHandle new_vh = _m.new_vertex(_m.calc_edge_midpoint(eh)); edge_midpoint[eh] = new_vh; is_original_vertex[new_vh] = false; } // Create new faces from original faces - for (typename mesh_t::FaceIter it = _m.faces_begin(), end = _m.faces_end(); it != end; ++it) { - FaceHandle fh = *it; + for (auto fh : _m.faces()) { std::vector new_corners; - for (typename mesh_t::FaceEdgeIter it = _m.fe_begin(fh), end = _m.fe_end(fh); it != end; ++it) { - EdgeHandle eh = *it; + for (auto eh : _m.fe_range(fh)) new_corners.push_back(edge_midpoint[eh]); - } _m.add_face(new_corners); } // Create new faces from original vertices - for (typename mesh_t::VertexIter it = _m.vertices_begin(), end = _m.vertices_end(); it != end; ++it) { - VertexHandle vh = *it; + for (auto vh : _m.vertices()) { if (is_original_vertex[vh]) { if (!_m.is_boundary(vh)) { std::vector new_corners; - for (typename mesh_t::VertexEdgeIter it = _m.ve_begin(vh), end = _m.ve_end(vh); it != end; ++it) { - EdgeHandle eh = *it; + for (auto eh : _m.ve_range(vh)) new_corners.push_back(edge_midpoint[eh]); - } std::reverse(new_corners.begin(), new_corners.end()); _m.add_face(new_corners); } } } - for (typename mesh_t::VertexIter it = _m.vertices_begin(), end = _m.vertices_end(); it != end; ++it) { - VertexHandle vh = *it; - if (is_original_vertex[vh]) { + for (auto vh : _m.vertices()) + if (is_original_vertex[vh]) _m.delete_vertex(vh); - } - } _m.garbage_collection(); } _m.release_face_status(); diff --git a/src/OpenMesh/Tools/Subdivider/Uniform/ModifiedButterFlyT.hh b/src/OpenMesh/Tools/Subdivider/Uniform/ModifiedButterFlyT.hh index 5825c9b8..78b8f806 100644 --- a/src/OpenMesh/Tools/Subdivider/Uniform/ModifiedButterFlyT.hh +++ b/src/OpenMesh/Tools/Subdivider/Uniform/ModifiedButterFlyT.hh @@ -39,13 +39,6 @@ * * * ========================================================================= */ -/*==========================================================================*\ -* * -* $Revision: 410 $ * -* $Date: 2010-06-17 12:45:58 +0200 (Do, 17. Jun 2010) $ * -* * -\*==========================================================================*/ - /** \file ModifiedButterFlyT.hh The modified butterfly scheme of Denis Zorin, Peter Schröder and Wim Sweldens, @@ -114,7 +107,7 @@ public: { init_weights(); } - ModifiedButterflyT( mesh_t& _m) : parent_t(_m) + explicit ModifiedButterflyT( mesh_t& _m) : parent_t(_m) { init_weights(); } @@ -124,7 +117,7 @@ public: public: - const char *name() const { return "Uniform Spectral"; } + const char *name() const override { return "Uniform Spectral"; } /// Pre-compute weights @@ -165,7 +158,7 @@ public: protected: - bool prepare( mesh_t& _m ) + bool prepare( mesh_t& _m ) override { _m.add_property( vp_pos_ ); _m.add_property( ep_pos_ ); @@ -173,7 +166,7 @@ protected: } - bool cleanup( mesh_t& _m ) + bool cleanup( mesh_t& _m ) override { _m.remove_property( vp_pos_ ); _m.remove_property( ep_pos_ ); @@ -181,50 +174,43 @@ protected: } - bool subdivide( MeshType& _m, size_t _n , const bool _update_points = true) + bool subdivide( MeshType& _m, size_t _n , const bool _update_points = true) override { ///TODO:Implement fixed positions - typename mesh_t::FaceIter fit, f_end; - typename mesh_t::EdgeIter eit, e_end; - typename mesh_t::VertexIter vit; - // Do _n subdivisions for (size_t i=0; i < _n; ++i) { // This is an interpolating scheme, old vertices remain the same. typename mesh_t::VertexIter initialVerticesEnd = _m.vertices_end(); - for ( vit = _m.vertices_begin(); vit != initialVerticesEnd; ++vit) - _m.property( vp_pos_, *vit ) = _m.point(*vit); + for ( auto vh : _m.vertices()) + _m.property( vp_pos_, vh ) = _m.point(vh); // Compute position for new vertices and store them in the edge property - for (eit=_m.edges_begin(); eit != _m.edges_end(); ++eit) - compute_midpoint( _m, *eit ); + for (auto eh : _m.edges()) + compute_midpoint( _m, eh); // Split each edge at midpoint and store precomputed positions (stored in // edge property ep_pos_) in the vertex property vp_pos_; // Attention! Creating new edges, hence make sure the loop ends correctly. - e_end = _m.edges_end(); - for (eit=_m.edges_begin(); eit != e_end; ++eit) - split_edge(_m, *eit ); + for (auto eh : _m.edges()) + split_edge(_m, eh ); // Commit changes in topology and reconsitute consistency // Attention! Creating new faces, hence make sure the loop ends correctly. - f_end = _m.faces_end(); - for (fit = _m.faces_begin(); fit != f_end; ++fit) - split_face(_m, *fit ); + for (auto fh : _m.faces()) + split_face(_m, fh ); // Commit changes in geometry - for ( vit = /*initialVerticesEnd;*/_m.vertices_begin(); - vit != _m.vertices_end(); ++vit) - _m.set_point(*vit, _m.property( vp_pos_, *vit ) ); + for ( auto vh : _m.vertices()) + _m.set_point(vh, _m.property( vp_pos_, vh ) ); #if defined(_DEBUG) || defined(DEBUG) // Now we have an consistent mesh! @@ -363,7 +349,11 @@ private: // topological modifiers _m.set_face_handle( new_heh, _m.face_handle(heh) ); _m.set_halfedge_handle( vh, new_heh); - _m.set_halfedge_handle( _m.face_handle(heh), heh ); + + // We cant reconnect a non existing face, so we skip this here if necessary + if ( !_m.is_boundary(heh) ) + _m.set_halfedge_handle( _m.face_handle(heh), heh ); + _m.set_halfedge_handle( vh1, opp_new_heh ); // Never forget this, when playing with the topology @@ -390,7 +380,7 @@ private: // geometry helper { pos = _m.point(a_0); pos += _m.point(a_1); - pos *= static_cast(9.0/16.0); + pos *= static_cast(9.0/16.0); typename mesh_t::Point tpos; if(_m.is_boundary(heh)) { @@ -403,7 +393,7 @@ private: // geometry helper tpos = _m.point(_m.to_vertex_handle(_m.next_halfedge_handle(opp_heh))); tpos += _m.point(_m.to_vertex_handle(_m.opposite_halfedge_handle(_m.prev_halfedge_handle(opp_heh)))); } - tpos *= static_cast(-1.0/16.0); + tpos *= static_cast(-1.0/16.0); pos += tpos; } else @@ -506,7 +496,7 @@ private: // geometry helper } else //at least one endpoint is [irregular and not in boundary] { - typename mesh_t::Point::value_type normFactor = static_cast(0.0); + RealType normFactor = static_cast(0.0); if(valence_a_0!=6 && !_m.is_boundary(a_0)) { diff --git a/src/OpenMesh/Tools/Subdivider/Uniform/Sqrt3InterpolatingSubdividerLabsikGreinerT.hh b/src/OpenMesh/Tools/Subdivider/Uniform/Sqrt3InterpolatingSubdividerLabsikGreinerT.hh index 903b39ba..d3b7199c 100644 --- a/src/OpenMesh/Tools/Subdivider/Uniform/Sqrt3InterpolatingSubdividerLabsikGreinerT.hh +++ b/src/OpenMesh/Tools/Subdivider/Uniform/Sqrt3InterpolatingSubdividerLabsikGreinerT.hh @@ -39,13 +39,6 @@ * * * ========================================================================= */ -/*==========================================================================*\ -* * -* $Revision: 410 $ * -* $Date: 2010-06-17 12:45:58 +0200 (Do, 17. Jun 2010) $ * -* * -\*==========================================================================*/ - /** \file Sqrt3InterpolatingSubdividerLabsikGreinerT.hh * * Interpolating Labsik Greiner Subdivider as described in @@ -126,7 +119,7 @@ public: InterpolatingSqrt3LGT(void) : parent_t() { init_weights(); } - InterpolatingSqrt3LGT(MeshType &_m) : parent_t(_m) + explicit InterpolatingSqrt3LGT(MeshType &_m) : parent_t(_m) { init_weights(); } virtual ~InterpolatingSqrt3LGT() {} @@ -135,7 +128,7 @@ public: public: - const char *name() const { return "Uniform Interpolating Sqrt3"; } + const char *name() const override { return "Uniform Interpolating Sqrt3"; } /// Pre-compute weights void init_weights(size_t _max_valence=50) @@ -177,7 +170,7 @@ public: protected: - bool prepare( MeshType& _m ) + bool prepare( MeshType& _m ) override { _m.request_edge_status(); _m.add_property( fp_pos_ ); @@ -190,7 +183,7 @@ protected: } - bool cleanup( MeshType& _m ) + bool cleanup( MeshType& _m ) override { _m.release_edge_status(); _m.remove_property( fp_pos_ ); @@ -200,7 +193,7 @@ protected: } - bool subdivide( MeshType& _m, size_t _n , const bool _update_points = true) + bool subdivide( MeshType& _m, size_t _n , const bool _update_points = true) override { ///TODO:Implement fixed positions @@ -416,7 +409,7 @@ private: typename MeshType::HalfedgeHandle heh; typename MeshType::VertexHandle vh1, vh2, vh3, vh4, vhl, vhr; - typename MeshType::Point zero(0,0,0), P1, P2, P3, P4; + typename MeshType::Point P1, P2, P3, P4; /* // *---------*---------* diff --git a/src/OpenMesh/Tools/Subdivider/Uniform/Sqrt3T.hh b/src/OpenMesh/Tools/Subdivider/Uniform/Sqrt3T.hh index 77e0e6b0..229bb692 100644 --- a/src/OpenMesh/Tools/Subdivider/Uniform/Sqrt3T.hh +++ b/src/OpenMesh/Tools/Subdivider/Uniform/Sqrt3T.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + /** \file Sqrt3T.hh @@ -117,7 +112,7 @@ public: Sqrt3T(void) : parent_t(), _1over3( real_t(1.0/3.0) ), _1over27( real_t(1.0/27.0) ) { init_weights(); } - Sqrt3T(MeshType &_m) : parent_t(_m), _1over3( real_t(1.0/3.0) ), _1over27( real_t(1.0/27.0) ) + explicit Sqrt3T(MeshType &_m) : parent_t(_m), _1over3( real_t(1.0/3.0) ), _1over27( real_t(1.0/27.0) ) { init_weights(); } virtual ~Sqrt3T() {} @@ -126,7 +121,7 @@ public: public: - const char *name() const { return "Uniform Sqrt3"; } + const char *name() const override { return "Uniform Sqrt3"; } /// Pre-compute weights @@ -140,7 +135,7 @@ public: protected: - bool prepare( MeshType& _m ) + bool prepare( MeshType& _m ) override { _m.request_edge_status(); _m.add_property( vp_pos_ ); @@ -153,7 +148,7 @@ protected: } - bool cleanup( MeshType& _m ) + bool cleanup( MeshType& _m ) override { _m.release_edge_status(); _m.remove_property( vp_pos_ ); @@ -162,44 +157,36 @@ protected: return true; } - bool subdivide( MeshType& _m, size_t _n , const bool _update_points = true) + bool subdivide( MeshType& _m, size_t _n , const bool _update_points = true) override { ///TODO:Implement fixed positions - typename MeshType::VertexIter vit; - typename MeshType::VertexVertexIter vvit; - typename MeshType::EdgeIter eit; - typename MeshType::FaceIter fit; - typename MeshType::FaceVertexIter fvit; - typename MeshType::VertexHandle vh; - typename MeshType::HalfedgeHandle heh; typename MeshType::Point pos(0,0,0), zero(0,0,0); size_t &gen = _m.property( mp_gen_ ); for (size_t l=0; l<_n; ++l) { // tag existing edges - for (eit=_m.edges_begin(); eit != _m.edges_end();++eit) + for (auto eh : _m.edges()) { - _m.status( *eit ).set_tagged( true ); - if ( (gen%2) && _m.is_boundary(*eit) ) - compute_new_boundary_points( _m, *eit ); // *) creates new vertices + _m.status( eh ).set_tagged( true ); + if ( (gen%2) && _m.is_boundary(eh) ) + compute_new_boundary_points( _m, eh ); // *) creates new vertices } // do relaxation of old vertices, but store new pos in property vp_pos_ - for (vit=_m.vertices_begin(); vit!=_m.vertices_end(); ++vit) + for (auto vh : _m.vertices()) { - if ( _m.is_boundary(*vit) ) + if ( _m.is_boundary(vh) ) { if ( gen%2 ) { - heh = _m.halfedge_handle(*vit); + auto heh = _m.halfedge_handle(vh); if (heh.is_valid()) // skip isolated newly inserted vertices *) { - typename OpenMesh::HalfedgeHandle - prev_heh = _m.prev_halfedge_handle(heh); + auto prev_heh = _m.prev_halfedge_handle(heh); assert( _m.is_boundary(heh ) ); assert( _m.is_boundary(prev_heh) ); @@ -208,60 +195,59 @@ protected: pos += _m.point(_m.from_vertex_handle(prev_heh)); pos *= real_t(4.0); - pos += real_t(19.0) * _m.point( *vit ); + pos += real_t(19.0) * _m.point( vh ); pos *= _1over27; - _m.property( vp_pos_, *vit ) = pos; + _m.property( vp_pos_, vh ) = pos; } } else - _m.property( vp_pos_, *vit ) = _m.point( *vit ); + _m.property( vp_pos_, vh ) = _m.point( vh ); } else { size_t valence=0; pos = zero; - for ( vvit = _m.vv_iter(*vit); vvit.is_valid(); ++vvit) + for ( auto vvh : _m.vv_range(vh)) { - pos += _m.point( *vvit ); + pos += _m.point( vvh ); ++valence; } pos *= weights_[ valence ].second; - pos += weights_[ valence ].first * _m.point(*vit); - _m.property( vp_pos_, *vit ) = pos; + pos += weights_[ valence ].first * _m.point(vh); + _m.property( vp_pos_, vh ) = pos; } } // insert new vertices, but store pos in vp_pos_ - typename MeshType::FaceIter fend = _m.faces_end(); - for (fit = _m.faces_begin();fit != fend; ++fit) + for (auto fh : _m.faces()) { - if ( (gen%2) && _m.is_boundary(*fit)) + if ( (gen%2) && _m.is_boundary(fh)) { - boundary_split( _m, *fit ); + boundary_split( _m, fh ); } else { - fvit = _m.fv_iter( *fit ); + auto fvit = _m.fv_iter( fh ); pos = _m.point( *fvit); pos += _m.point(*(++fvit)); pos += _m.point(*(++fvit)); pos *= _1over3; - vh = _m.add_vertex( zero ); + auto vh = _m.add_vertex( zero ); _m.property( vp_pos_, vh ) = pos; - _m.split( *fit, vh ); + _m.split( fh, vh ); } } // commit new positions (now iterating over all vertices) - for (vit=_m.vertices_begin();vit != _m.vertices_end(); ++vit) - _m.set_point(*vit, _m.property( vp_pos_, *vit ) ); + for (auto vh : _m.vertices()) + _m.set_point(vh, _m.property( vp_pos_, vh ) ); // flip old edges - for (eit=_m.edges_begin(); eit != _m.edges_end(); ++eit) - if ( _m.status( *eit ).tagged() && !_m.is_boundary( *eit ) ) - _m.flip(*eit); + for (auto eh : _m.edges()) + if ( _m.status( eh ).tagged() && !_m.is_boundary( eh ) ) + _m.flip(eh); // Now we have an consistent mesh! ASSERT_CONSISTENCY( MeshType, _m ); diff --git a/src/OpenMesh/Tools/Subdivider/Uniform/SubdividerT.hh b/src/OpenMesh/Tools/Subdivider/Uniform/SubdividerT.hh index 08b2c0b4..d39070f8 100644 --- a/src/OpenMesh/Tools/Subdivider/Uniform/SubdividerT.hh +++ b/src/OpenMesh/Tools/Subdivider/Uniform/SubdividerT.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + /** \file SubdividerT.hh @@ -107,7 +102,7 @@ public: /// Constructor to be used with interface 1 (calls attach()) /// \see operator()( MeshType&, size_t ) - explicit SubdividerT( MeshType &_m ) : attached_(NULL) { attach(_m); } + explicit SubdividerT( MeshType &_m ) : attached_(nullptr) { attach(_m); } //@} @@ -162,7 +157,7 @@ public: /// \name Interface 2 if ( attached_ ) { cleanup( *attached_ ); - attached_ = NULL; + attached_ = nullptr; } } //@} diff --git a/src/OpenMesh/Tools/Tools.pro b/src/OpenMesh/Tools/Tools.pro deleted file mode 100644 index 50933420..00000000 --- a/src/OpenMesh/Tools/Tools.pro +++ /dev/null @@ -1,45 +0,0 @@ -################################################################################ -# -################################################################################ - -include( $$TOPDIR/qmake/all.include ) - -Library() - -contains( OPENFLIPPER , OpenFlipper ){ - DESTDIR = $${TOPDIR}/OpenMesh/lib -} else { - DESTDIR = $${TOPDIR}/lib -} - -DIRECTORIES = . Decimater Smoother Subdivider/Adaptive/Composite \ - Subdivider/Uniform/Composite Subdivider/Uniform \ - Utils - -INCLUDEPATH += ../.. - -CONFIG( debug, debug|release ){ - TARGET = OpenMeshToolsd -} else { - TARGET = OpenMeshTools -} - -win32 { - DEFINES += _USE_MATH_DEFINES NOMINMAX - CONFIG += static -} - -macx { - # Set library binary header to the correct path - QMAKE_LFLAGS_SONAME = -install_name$${LITERAL_WHITESPACE}$${DESTDIR}/ - export(QMAKE_LFLAGS_SONAME) -} - -# Input -HEADERS += $$getFilesFromDir($$DIRECTORIES,*.hh) -SOURCES += $$getFilesFromDir($$DIRECTORIES,*.c) -SOURCES += $$getFilesFromDir($$DIRECTORIES,*.cc) -FORMS += $$getFilesFromDir($$DIRECTORIES,*.ui) - - -################################################################################ diff --git a/src/OpenMesh/Tools/Utils/Config.hh b/src/OpenMesh/Tools/Utils/Config.hh index 4bfe4e98..c023c908 100644 --- a/src/OpenMesh/Tools/Utils/Config.hh +++ b/src/OpenMesh/Tools/Utils/Config.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + /** \file Tools/Utils/Config.hh */ diff --git a/src/OpenMesh/Tools/Utils/GLConstAsString.hh b/src/OpenMesh/Tools/Utils/GLConstAsString.hh index 1e6bd7c5..d5c0286f 100644 --- a/src/OpenMesh/Tools/Utils/GLConstAsString.hh +++ b/src/OpenMesh/Tools/Utils/GLConstAsString.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= // @@ -60,7 +55,6 @@ //== INCLUDES ================================================================= #include -#include //== FORWARDDECLARATIONS ====================================================== diff --git a/src/OpenMesh/Tools/Utils/Gnuplot.cc b/src/OpenMesh/Tools/Utils/Gnuplot.cc index a70ca1ad..88e91607 100644 --- a/src/OpenMesh/Tools/Utils/Gnuplot.cc +++ b/src/OpenMesh/Tools/Utils/Gnuplot.cc @@ -38,7 +38,7 @@ # define access _access # define ACCESS_OK 0 # define PATH_SEP ";" -# define MKTEMP_AND_CHECK_FAILED(name) (_mktemp(name) == NULL) +# define MKTEMP_AND_CHECK_FAILED(name) (_mktemp(name) == nullptr) #else # define ACCESS_OK X_OK # define PATH_SEP ":" @@ -368,7 +368,7 @@ void Gnuplot::plot_x(vector d, const string &title) // //open temporary files for output #ifdef WIN32 - if ( _mktemp(name) == NULL) + if ( _mktemp(name) == nullptr) #else if ( mkstemp(name) == -1 ) #endif diff --git a/src/OpenMesh/Tools/Utils/HeapT.hh b/src/OpenMesh/Tools/Utils/HeapT.hh index 63c27c25..7f1b3a8e 100644 --- a/src/OpenMesh/Tools/Utils/HeapT.hh +++ b/src/OpenMesh/Tools/Utils/HeapT.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + /** \file Tools/Utils/HeapT.hh A generic heap class @@ -157,7 +152,7 @@ public: {} #else /// Construct with a given \c HeapIterface. - HeapT(const HeapInterface &_interface) + explicit HeapT(const HeapInterface &_interface) : HeapVector(), interface_(_interface) {} #endif @@ -263,9 +258,9 @@ public: bool check() { bool ok(true); - unsigned int i, j; - for (i=0; i:: downheap(size_t _idx) { const HeapEntry h = entry(_idx); - size_t childIdx; const size_t s = size(); while(_idx < s) { - childIdx = left(_idx); + size_t childIdx = left(_idx); if (childIdx >= s) break; if ((childIdx + 1 < s) && (interface_.less(entry(childIdx + 1), entry(childIdx)))) diff --git a/src/OpenMesh/Tools/Utils/MeshCheckerT.hh b/src/OpenMesh/Tools/Utils/MeshCheckerT.hh index 2357ab26..193359d8 100644 --- a/src/OpenMesh/Tools/Utils/MeshCheckerT.hh +++ b/src/OpenMesh/Tools/Utils/MeshCheckerT.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef OPENMESH_MESHCHECKER_HH @@ -124,7 +119,7 @@ private: //============================================================================= #if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_MESHCHECKER_C) #define OPENMESH_MESHCHECKER_TEMPLATES -#include "MeshCheckerT.cc" +#include "MeshCheckerT_impl.hh" #endif //============================================================================= #endif // OPENMESH_MESHCHECKER_HH defined diff --git a/src/OpenMesh/Tools/Utils/MeshCheckerT.cc b/src/OpenMesh/Tools/Utils/MeshCheckerT_impl.hh similarity index 94% rename from src/OpenMesh/Tools/Utils/MeshCheckerT.cc rename to src/OpenMesh/Tools/Utils/MeshCheckerT_impl.hh index 2c5f80df..a8c533f1 100644 --- a/src/OpenMesh/Tools/Utils/MeshCheckerT.cc +++ b/src/OpenMesh/Tools/Utils/MeshCheckerT_impl.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #define OPENMESH_MESHCHECKER_C diff --git a/src/OpenMesh/Tools/Utils/NumLimitsT.hh b/src/OpenMesh/Tools/Utils/NumLimitsT.hh index 39117ebc..9c679f36 100644 --- a/src/OpenMesh/Tools/Utils/NumLimitsT.hh +++ b/src/OpenMesh/Tools/Utils/NumLimitsT.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + /** \file Tools/Utils/NumLimitsT.hh Temporary solution until std::numeric_limits is standard. diff --git a/src/OpenMesh/Tools/Utils/StripifierT.hh b/src/OpenMesh/Tools/Utils/StripifierT.hh index 61f5182f..21ebc00c 100644 --- a/src/OpenMesh/Tools/Utils/StripifierT.hh +++ b/src/OpenMesh/Tools/Utils/StripifierT.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= // @@ -93,7 +88,7 @@ public: /// Default constructor - StripifierT(Mesh& _mesh); + explicit StripifierT(Mesh& _mesh); /// Destructor ~StripifierT(); @@ -151,7 +146,7 @@ private: //============================================================================= #if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_STRIPIFIERT_C) #define OPENMESH_STRIPIFIERT_TEMPLATES -#include "StripifierT.cc" +#include "StripifierT_impl.hh" #endif //============================================================================= #endif // OPENMESH_STRIPIFIERT_HH defined diff --git a/src/OpenMesh/Tools/Utils/StripifierT.cc b/src/OpenMesh/Tools/Utils/StripifierT_impl.hh similarity index 95% rename from src/OpenMesh/Tools/Utils/StripifierT.cc rename to src/OpenMesh/Tools/Utils/StripifierT_impl.hh index 8bd33727..3f86d1f3 100644 --- a/src/OpenMesh/Tools/Utils/StripifierT.cc +++ b/src/OpenMesh/Tools/Utils/StripifierT_impl.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= // diff --git a/src/OpenMesh/Tools/Utils/TestingFramework.hh b/src/OpenMesh/Tools/Utils/TestingFramework.hh index 9c824388..ee34f721 100644 --- a/src/OpenMesh/Tools/Utils/TestingFramework.hh +++ b/src/OpenMesh/Tools/Utils/TestingFramework.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef TESTINGFRAMEWORK_HH #define TESTINGFRAMEWORK_HH diff --git a/src/OpenMesh/Tools/Utils/Timer.cc b/src/OpenMesh/Tools/Utils/Timer.cc index 98d6e409..459db75d 100644 --- a/src/OpenMesh/Tools/Utils/Timer.cc +++ b/src/OpenMesh/Tools/Utils/Timer.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef DOXY_IGNORE_THIS // ---------------------------------------------------------------------------- @@ -105,11 +100,11 @@ public: TimerImplWin32(void); ~TimerImplWin32(void) { ; } - virtual void reset(void); - virtual void start(void); - virtual void stop(void); - virtual void cont(void); - virtual double seconds(void) const; + virtual void reset(void) override; + virtual void start(void) override; + virtual void stop(void) override; + virtual void cont(void) override; + virtual double seconds(void) const override; }; TimerImplWin32::TimerImplWin32(void) @@ -188,7 +183,7 @@ protected: }; // ----------------------------------------------------------- gettimeofday ---- -#elif (defined(__GNUC__) || (defined(__INTEL_COMPILER) && !defined(WIN32))) && !defined(__MINGW32__) +#elif (defined(__GNUC__) && !defined(__FreeBSD__) || (defined(__INTEL_COMPILER) && !defined(WIN32))) && !defined(__MINGW32__) # include # include @@ -203,10 +198,10 @@ public: ~TimerImplGToD() { } - virtual void reset(void) { seconds_ = 0.0; } - virtual void start(void) { seconds_ = 0.0; gettimeofday( &start_, &tz_ ); } + virtual void reset(void) override { seconds_ = 0.0; } + virtual void start(void) override { seconds_ = 0.0; gettimeofday( &start_, &tz_ ); } - virtual void stop(void) + virtual void stop(void) override { gettimeofday( &stop_, &tz_ ); @@ -214,9 +209,9 @@ public: seconds_ += (double)(stop_.tv_usec- start_.tv_usec)*1e-6; } - virtual void cont(void) { gettimeofday( &start_, &tz_); } + virtual void cont(void) override { gettimeofday( &start_, &tz_); } - virtual double seconds() const { return seconds_; } + virtual double seconds() const override { return seconds_; } private: @@ -239,11 +234,11 @@ public: TimerImplStd() : freq_(clockticks),count_(0),start_(0) { reset(); } ~TimerImplStd() { ; } - virtual void reset(void) { count_ = 0; } - virtual void start(void) { count_ = 0; start_ = clock(); } - virtual void stop(void); - virtual void cont(void) { start_ = clock(); } - virtual double seconds(void) const { return (double)count_/(double)freq_; } + virtual void reset(void) override { count_ = 0; } + virtual void start(void) override { count_ = 0; start_ = clock(); } + virtual void stop(void) override; + virtual void cont(void) override { start_ = clock(); } + virtual double seconds(void) const override { return (double)count_/(double)freq_; } protected: unsigned long freq_; @@ -276,7 +271,7 @@ Timer::Timer(void) : # else impl_ = new TimerImplPosix; # endif -#elif (defined(__GNUC__) || (defined(__INTEL_COMPILER) && !defined(WIN32)) ) && !defined(__MINGW32__) +#elif (defined(__GNUC__) && !defined(__FreeBSD__) || (defined(__INTEL_COMPILER) && !defined(WIN32)) ) && !defined(__MINGW32__) impl_ = new TimerImplGToD; #else impl_ = new TimerImplStd; diff --git a/src/OpenMesh/Tools/Utils/Timer.hh b/src/OpenMesh/Tools/Utils/Timer.hh index 91347c21..12fa6be0 100644 --- a/src/OpenMesh/Tools/Utils/Timer.hh +++ b/src/OpenMesh/Tools/Utils/Timer.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef TIMER_HH #define TIMER_HH diff --git a/src/OpenMesh/Tools/Utils/conio.cc b/src/OpenMesh/Tools/Utils/conio.cc index 985fbddb..9b0debf9 100644 --- a/src/OpenMesh/Tools/Utils/conio.cc +++ b/src/OpenMesh/Tools/Utils/conio.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #include @@ -125,7 +120,7 @@ int kbhit(void) error += tcsetattr(0, TCSANOW, &Otty); tv.tv_sec = 0; tv.tv_usec = 100; /* insert at least a minimal delay */ - select(1, NULL, NULL, NULL, &tv); + select(1, nullptr, nullptr, nullptr, &tv); } return (error == 0 ? cnt : -1 ); } diff --git a/src/OpenMesh/Tools/Utils/conio.hh b/src/OpenMesh/Tools/Utils/conio.hh index b4db158f..58fe5408 100644 --- a/src/OpenMesh/Tools/Utils/conio.hh +++ b/src/OpenMesh/Tools/Utils/conio.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + #ifndef OPENMESH_UTILS_CONIO_HH #define OPENMESH_UTILS_CONIO_HH diff --git a/src/OpenMesh/Tools/Utils/getopt.h b/src/OpenMesh/Tools/Utils/getopt.h index 59600d73..d2d7f918 100644 --- a/src/OpenMesh/Tools/Utils/getopt.h +++ b/src/OpenMesh/Tools/Utils/getopt.h @@ -21,7 +21,7 @@ #endif -#elif defined __APPLE__ +#elif defined __APPLE__ || defined(__FreeBSD__) #include #else #include diff --git a/src/OpenMesh/Tools/VDPM/MeshTraits.hh b/src/OpenMesh/Tools/VDPM/MeshTraits.hh index 438d9266..79acb9ac 100644 --- a/src/OpenMesh/Tools/VDPM/MeshTraits.hh +++ b/src/OpenMesh/Tools/VDPM/MeshTraits.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= // diff --git a/src/OpenMesh/Tools/VDPM/StreamingDef.hh b/src/OpenMesh/Tools/VDPM/StreamingDef.hh index d3539df4..bd187856 100644 --- a/src/OpenMesh/Tools/VDPM/StreamingDef.hh +++ b/src/OpenMesh/Tools/VDPM/StreamingDef.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= // diff --git a/src/OpenMesh/Tools/VDPM/VFront.cc b/src/OpenMesh/Tools/VDPM/VFront.cc index 8c50e910..b83a9704 100644 --- a/src/OpenMesh/Tools/VDPM/VFront.cc +++ b/src/OpenMesh/Tools/VDPM/VFront.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= // diff --git a/src/OpenMesh/Tools/VDPM/VFront.hh b/src/OpenMesh/Tools/VDPM/VFront.hh index a53dc0c7..1d77a6bb 100644 --- a/src/OpenMesh/Tools/VDPM/VFront.hh +++ b/src/OpenMesh/Tools/VDPM/VFront.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= // diff --git a/src/OpenMesh/Tools/VDPM/VHierarchy.cc b/src/OpenMesh/Tools/VDPM/VHierarchy.cc index f28be46d..233abb73 100644 --- a/src/OpenMesh/Tools/VDPM/VHierarchy.cc +++ b/src/OpenMesh/Tools/VDPM/VHierarchy.cc @@ -37,144 +37,139 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * - * ========================================================================= */ - -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ - -//============================================================================= -// -// CLASS newClass - IMPLEMENTATION -// -//============================================================================= - - -//== INCLUDES ================================================================= - -#include - - -//== NAMESPACES =============================================================== - -namespace OpenMesh { -namespace VDPM { - -//== IMPLEMENTATION ========================================================== - - -VHierarchy:: + * ========================================================================= */ + + + +//============================================================================= +// +// CLASS newClass - IMPLEMENTATION +// +//============================================================================= + + +//== INCLUDES ================================================================= + +#include + + +//== NAMESPACES =============================================================== + +namespace OpenMesh { +namespace VDPM { + +//== IMPLEMENTATION ========================================================== + + +VHierarchy:: VHierarchy() : - n_roots_(0), tree_id_bits_(0) -{ - clear(); -} - -void -VHierarchy:: -set_num_roots(unsigned int _n_roots) -{ - n_roots_ = _n_roots; - - tree_id_bits_ = 0; - while (n_roots_ > ((unsigned int) 0x00000001 << tree_id_bits_)) - ++tree_id_bits_; -} - - -VHierarchyNodeHandle -VHierarchy:: -add_node() -{ - return add_node(VHierarchyNode()); -} - -VHierarchyNodeHandle -VHierarchy:: -add_node(const VHierarchyNode &_node) -{ - nodes_.push_back(_node); - - return VHierarchyNodeHandle(int(nodes_.size() - 1)); -} - - -void -VHierarchy:: -make_children(VHierarchyNodeHandle &_parent_handle) -{ - VHierarchyNodeHandle lchild_handle = add_node(); - VHierarchyNodeHandle rchild_handle = add_node(); - - VHierarchyNode &parent = node(_parent_handle); - VHierarchyNode &lchild = node(lchild_handle); - VHierarchyNode &rchild = node(rchild_handle); - - parent.set_children_handle(lchild_handle); - lchild.set_parent_handle(_parent_handle); - rchild.set_parent_handle(_parent_handle); - - lchild.set_index(VHierarchyNodeIndex(parent.node_index().tree_id(tree_id_bits_), 2*parent.node_index().node_id(tree_id_bits_), tree_id_bits_)); - rchild.set_index(VHierarchyNodeIndex(parent.node_index().tree_id(tree_id_bits_), 2*parent.node_index().node_id(tree_id_bits_)+1, tree_id_bits_)); -} - -VHierarchyNodeHandle -VHierarchy:: -node_handle(VHierarchyNodeIndex _node_index) -{ - if (_node_index.is_valid(tree_id_bits_) != true) - return InvalidVHierarchyNodeHandle; - - VHierarchyNodeHandle node_handle = root_handle(_node_index.tree_id(tree_id_bits_)); - unsigned int node_id = _node_index.node_id(tree_id_bits_); - unsigned int flag = 0x80000000; - - while (!(node_id & flag)) flag >>= 1; - flag >>= 1; - - while (flag > 0 && is_leaf_node(node_handle) != true) - { - if (node_id & flag) // 1: rchild - { - node_handle = rchild_handle(node_handle); - } - else // 0: lchild - { - node_handle = lchild_handle(node_handle); - } - flag >>= 1; - } - - return node_handle; -} - -bool -VHierarchy:: -is_ancestor(VHierarchyNodeIndex _ancestor_index, VHierarchyNodeIndex _descendent_index) -{ - if (_ancestor_index.tree_id(tree_id_bits_) != _descendent_index.tree_id(tree_id_bits_)) - return false; - - unsigned int ancestor_node_id = _ancestor_index.node_id(tree_id_bits_); - unsigned int descendent_node_id = _descendent_index.node_id(tree_id_bits_); - - if (ancestor_node_id > descendent_node_id) - return false; - - while (descendent_node_id > 0) - { - if (ancestor_node_id == descendent_node_id) - return true; - descendent_node_id >>= 1; // descendent_node_id /= 2 - } - - return false; -} - -//============================================================================= -} // namespace VDPM -} // namespace OpenMesh -//============================================================================= + n_roots_(0), tree_id_bits_(0) +{ + clear(); +} + +void +VHierarchy:: +set_num_roots(unsigned int _n_roots) +{ + n_roots_ = _n_roots; + + tree_id_bits_ = 0; + while (n_roots_ > ((unsigned int) 0x00000001 << tree_id_bits_)) + ++tree_id_bits_; +} + + +VHierarchyNodeHandle +VHierarchy:: +add_node() +{ + return add_node(VHierarchyNode()); +} + +VHierarchyNodeHandle +VHierarchy:: +add_node(const VHierarchyNode &_node) +{ + nodes_.push_back(_node); + + return VHierarchyNodeHandle(int(nodes_.size() - 1)); +} + + +void +VHierarchy:: +make_children(VHierarchyNodeHandle &_parent_handle) +{ + VHierarchyNodeHandle lchild_handle = add_node(); + VHierarchyNodeHandle rchild_handle = add_node(); + + VHierarchyNode &parent = node(_parent_handle); + VHierarchyNode &lchild = node(lchild_handle); + VHierarchyNode &rchild = node(rchild_handle); + + parent.set_children_handle(lchild_handle); + lchild.set_parent_handle(_parent_handle); + rchild.set_parent_handle(_parent_handle); + + lchild.set_index(VHierarchyNodeIndex(parent.node_index().tree_id(tree_id_bits_), 2*parent.node_index().node_id(tree_id_bits_), tree_id_bits_)); + rchild.set_index(VHierarchyNodeIndex(parent.node_index().tree_id(tree_id_bits_), 2*parent.node_index().node_id(tree_id_bits_)+1, tree_id_bits_)); +} + +VHierarchyNodeHandle +VHierarchy:: +node_handle(VHierarchyNodeIndex _node_index) +{ + if (_node_index.is_valid(tree_id_bits_) != true) + return InvalidVHierarchyNodeHandle; + + VHierarchyNodeHandle node_handle = root_handle(_node_index.tree_id(tree_id_bits_)); + unsigned int node_id = _node_index.node_id(tree_id_bits_); + unsigned int flag = 0x80000000; + + while (!(node_id & flag)) flag >>= 1; + flag >>= 1; + + while (flag > 0 && is_leaf_node(node_handle) != true) + { + if (node_id & flag) // 1: rchild + { + node_handle = rchild_handle(node_handle); + } + else // 0: lchild + { + node_handle = lchild_handle(node_handle); + } + flag >>= 1; + } + + return node_handle; +} + +bool +VHierarchy:: +is_ancestor(VHierarchyNodeIndex _ancestor_index, VHierarchyNodeIndex _descendent_index) +{ + if (_ancestor_index.tree_id(tree_id_bits_) != _descendent_index.tree_id(tree_id_bits_)) + return false; + + unsigned int ancestor_node_id = _ancestor_index.node_id(tree_id_bits_); + unsigned int descendent_node_id = _descendent_index.node_id(tree_id_bits_); + + if (ancestor_node_id > descendent_node_id) + return false; + + while (descendent_node_id > 0) + { + if (ancestor_node_id == descendent_node_id) + return true; + descendent_node_id >>= 1; // descendent_node_id /= 2 + } + + return false; +} + +//============================================================================= +} // namespace VDPM +} // namespace OpenMesh +//============================================================================= diff --git a/src/OpenMesh/Tools/VDPM/VHierarchy.hh b/src/OpenMesh/Tools/VDPM/VHierarchy.hh index 0eca2d61..66d5a02e 100644 --- a/src/OpenMesh/Tools/VDPM/VHierarchy.hh +++ b/src/OpenMesh/Tools/VDPM/VHierarchy.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= // diff --git a/src/OpenMesh/Tools/VDPM/VHierarchyNode.hh b/src/OpenMesh/Tools/VDPM/VHierarchyNode.hh index 435ba711..ba892b94 100644 --- a/src/OpenMesh/Tools/VDPM/VHierarchyNode.hh +++ b/src/OpenMesh/Tools/VDPM/VHierarchyNode.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= // @@ -96,7 +91,7 @@ class VHierarchyNode { public: - VHierarchyNode() :radius_(0.0f), sin_square_(0.0f),mue_square_(0.0f), sigma_square_(0.0f) { } + VHierarchyNode() :radius_(0.0f), normal_(0.0f), sin_square_(0.0f),mue_square_(0.0f), sigma_square_(0.0f) { } /// Returns true, if node is root else false. bool is_root() const diff --git a/src/OpenMesh/Tools/VDPM/VHierarchyNodeIndex.cc b/src/OpenMesh/Tools/VDPM/VHierarchyNodeIndex.cc index c5c1029e..4c553064 100644 --- a/src/OpenMesh/Tools/VDPM/VHierarchyNodeIndex.cc +++ b/src/OpenMesh/Tools/VDPM/VHierarchyNodeIndex.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= // diff --git a/src/OpenMesh/Tools/VDPM/VHierarchyNodeIndex.hh b/src/OpenMesh/Tools/VDPM/VHierarchyNodeIndex.hh index 5b17d8ec..928b14fe 100644 --- a/src/OpenMesh/Tools/VDPM/VHierarchyNodeIndex.hh +++ b/src/OpenMesh/Tools/VDPM/VHierarchyNodeIndex.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= // diff --git a/src/OpenMesh/Tools/VDPM/VHierarchyWindow.cc b/src/OpenMesh/Tools/VDPM/VHierarchyWindow.cc index b3aea8f9..4a97cda7 100644 --- a/src/OpenMesh/Tools/VDPM/VHierarchyWindow.cc +++ b/src/OpenMesh/Tools/VDPM/VHierarchyWindow.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= // @@ -78,7 +73,7 @@ namespace VDPM { VHierarchyWindow:: VHierarchyWindow() : - vhierarchy_(NULL), buffer_(NULL),buffer_min_ (0), buffer_max_(0), current_pos_(0) , window_min_(0), window_max_(0), n_shift_(0) + vhierarchy_(nullptr), buffer_(nullptr),buffer_min_ (0), buffer_max_(0), current_pos_(0) , window_min_(0), window_max_(0), n_shift_(0) { } @@ -86,7 +81,7 @@ VHierarchyWindow() : VHierarchyWindow:: VHierarchyWindow(VHierarchy &_vhierarchy) : - vhierarchy_(&_vhierarchy),buffer_(NULL),buffer_min_ (0), buffer_max_(0), current_pos_(0) , window_min_(0), window_max_(0) ,n_shift_(0) + vhierarchy_(&_vhierarchy),buffer_(nullptr),buffer_min_ (0), buffer_max_(0), current_pos_(0) , window_min_(0), window_max_(0) ,n_shift_(0) { } @@ -94,7 +89,7 @@ VHierarchyWindow(VHierarchy &_vhierarchy) : VHierarchyWindow:: ~VHierarchyWindow(void) { - if (buffer_ != NULL) + if (buffer_ != nullptr) free(buffer_); } @@ -143,7 +138,7 @@ update_buffer(VHierarchyNodeHandle _node_handle) void VHierarchyWindow::init(VHierarchyNodeHandleContainer &_roots) { - if (buffer_ != NULL) + if (buffer_ != nullptr) free(buffer_); buffer_min_ = 0; diff --git a/src/OpenMesh/Tools/VDPM/VHierarchyWindow.hh b/src/OpenMesh/Tools/VDPM/VHierarchyWindow.hh index a490e57b..9aff879e 100644 --- a/src/OpenMesh/Tools/VDPM/VHierarchyWindow.hh +++ b/src/OpenMesh/Tools/VDPM/VHierarchyWindow.hh @@ -37,188 +37,183 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * - * ========================================================================= */ - -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ - -//============================================================================= -// -// CLASS newClass -// -//============================================================================= - -#ifndef OPENMESH_VDPROGMESH_VHIERARCHYWINDOWS_HH -#define OPENMESH_VDPROGMESH_VHIERARCHYWINDOWS_HH - - -//== INCLUDES ================================================================= - -#include -#include - -//== FORWARDDECLARATIONS ====================================================== - - -//== NAMESPACES =============================================================== - -namespace OpenMesh { -namespace VDPM { - -//== CLASS DEFINITION ========================================================= - - -/** \todo VHierarchyWindow documentation -*/ -class VHierarchyWindow -{ -private: - - // reference of vertex hierarchy - VHierarchy *vhierarchy_; - - // bits buffer (byte units) - unsigned char *buffer_; - int buffer_min_; - size_t buffer_max_; - int current_pos_; - - // window (byte units) - int window_min_; - int window_max_; - - - // # of right shift (bit units) - unsigned char n_shift_; // [0, 7] - - unsigned char flag8(unsigned char n_shift) const - { return 0x80 >> n_shift; } - - unsigned char flag8(VHierarchyNodeHandle _node_handle) const - { - assert(_node_handle.idx() >= 0); - return 0x80 >> (unsigned int) (_node_handle.idx() % 8); - } - int byte_idx(VHierarchyNodeHandle _node_handle) const - { - assert(_node_handle.idx() >= 0); - return _node_handle.idx() / 8; - } - int buffer_idx(VHierarchyNodeHandle _node_handle) const - { return byte_idx(_node_handle) - buffer_min_; } - - bool before_window(VHierarchyNodeHandle _node_handle) const - { return (_node_handle.idx()/8 < window_min_) ? true : false; } - - bool after_window(VHierarchyNodeHandle _node_handle) const - { return (_node_handle.idx()/8 < window_max_) ? false : true; } - - bool underflow(VHierarchyNodeHandle _node_handle) const - { return (_node_handle.idx()/8 < buffer_min_) ? true : false; } - - bool overflow(VHierarchyNodeHandle _node_handle) const - { return (_node_handle.idx()/8 < int(buffer_max_) ) ? false : true; } - - bool update_buffer(VHierarchyNodeHandle _node_handle); - -public: - VHierarchyWindow(); - VHierarchyWindow(VHierarchy &_vhierarchy); - ~VHierarchyWindow(void); - - void set_vertex_hierarchy(VHierarchy &_vhierarchy) - { vhierarchy_ = &_vhierarchy; } - - void begin() - { - int new_window_min = window_min_; - for (current_pos_=window_min_-buffer_min_; - current_pos_ < window_size(); ++current_pos_) - { - if (buffer_[current_pos_] == 0) - ++new_window_min; - else - { - n_shift_ = 0; - while ((buffer_[current_pos_] & flag8(n_shift_)) == 0) - ++n_shift_; - break; - } - } - window_min_ = new_window_min; - } - - void next() - { - ++n_shift_; - if (n_shift_ == 8) - { - n_shift_ = 0; - ++current_pos_; - } - - while (current_pos_ < window_max_-buffer_min_) - { - if (buffer_[current_pos_] != 0) // if the current byte has non-zero bits - { - while (n_shift_ != 8) - { - if ((buffer_[current_pos_] & flag8(n_shift_)) != 0) - return; // find 1 bit in the current byte - ++n_shift_; - } - } - n_shift_ = 0; - ++current_pos_; - } - } - bool end() { return !(current_pos_ < window_max_-buffer_min_); } - - int window_size() const { return window_max_ - window_min_; } - size_t buffer_size() const { return buffer_max_ - buffer_min_; } - - VHierarchyNodeHandle node_handle() - { - return VHierarchyNodeHandle(8*(buffer_min_+current_pos_) + (int)n_shift_); - } - - void activate(VHierarchyNodeHandle _node_handle) - { - update_buffer(_node_handle); - buffer_[buffer_idx(_node_handle)] |= flag8(_node_handle); - window_min_ = std::min(window_min_, byte_idx(_node_handle)); - window_max_ = std::max(window_max_, 1+byte_idx(_node_handle)); - } - - - void inactivate(VHierarchyNodeHandle _node_handle) - { - if (is_active(_node_handle) != true) return; - buffer_[buffer_idx(_node_handle)] ^= flag8(_node_handle); - } - - - bool is_active(VHierarchyNodeHandle _node_handle) const - { - if (before_window(_node_handle) == true || - after_window(_node_handle) == true) - return false; - return ((buffer_[buffer_idx(_node_handle)] & flag8(_node_handle)) > 0); - } - - void init(VHierarchyNodeHandleContainer &_roots); - void update_with_vsplit(VHierarchyNodeHandle _parent_handle); - void update_with_ecol(VHierarchyNodeHandle _parent_handle); -}; - -//============================================================================= -} // namespace VDPM -} // namespace OpenMesh -//============================================================================= -#endif // OPENMESH_VDPROGMESH_VHIERARCHYWINDOWS_HH -//============================================================================= - + * ========================================================================= */ + + + +//============================================================================= +// +// CLASS newClass +// +//============================================================================= + +#ifndef OPENMESH_VDPROGMESH_VHIERARCHYWINDOWS_HH +#define OPENMESH_VDPROGMESH_VHIERARCHYWINDOWS_HH + + +//== INCLUDES ================================================================= + +#include +#include + +//== FORWARDDECLARATIONS ====================================================== + + +//== NAMESPACES =============================================================== + +namespace OpenMesh { +namespace VDPM { + +//== CLASS DEFINITION ========================================================= + + +/** \todo VHierarchyWindow documentation +*/ +class VHierarchyWindow +{ +private: + + // reference of vertex hierarchy + VHierarchy *vhierarchy_; + + // bits buffer (byte units) + unsigned char *buffer_; + int buffer_min_; + size_t buffer_max_; + int current_pos_; + + // window (byte units) + int window_min_; + int window_max_; + + + // # of right shift (bit units) + unsigned char n_shift_; // [0, 7] + + unsigned char flag8(unsigned char n_shift) const + { return 0x80 >> n_shift; } + + unsigned char flag8(VHierarchyNodeHandle _node_handle) const + { + assert(_node_handle.idx() >= 0); + return 0x80 >> (unsigned int) (_node_handle.idx() % 8); + } + int byte_idx(VHierarchyNodeHandle _node_handle) const + { + assert(_node_handle.idx() >= 0); + return _node_handle.idx() / 8; + } + int buffer_idx(VHierarchyNodeHandle _node_handle) const + { return byte_idx(_node_handle) - buffer_min_; } + + bool before_window(VHierarchyNodeHandle _node_handle) const + { return (_node_handle.idx()/8 < window_min_) ? true : false; } + + bool after_window(VHierarchyNodeHandle _node_handle) const + { return (_node_handle.idx()/8 < window_max_) ? false : true; } + + bool underflow(VHierarchyNodeHandle _node_handle) const + { return (_node_handle.idx()/8 < buffer_min_) ? true : false; } + + bool overflow(VHierarchyNodeHandle _node_handle) const + { return (_node_handle.idx()/8 < int(buffer_max_) ) ? false : true; } + + bool update_buffer(VHierarchyNodeHandle _node_handle); + +public: + VHierarchyWindow(); + explicit VHierarchyWindow(VHierarchy &_vhierarchy); + ~VHierarchyWindow(void); + + void set_vertex_hierarchy(VHierarchy &_vhierarchy) + { vhierarchy_ = &_vhierarchy; } + + void begin() + { + int new_window_min = window_min_; + for (current_pos_=window_min_-buffer_min_; + current_pos_ < window_size(); ++current_pos_) + { + if (buffer_[current_pos_] == 0) + ++new_window_min; + else + { + n_shift_ = 0; + while ((buffer_[current_pos_] & flag8(n_shift_)) == 0) + ++n_shift_; + break; + } + } + window_min_ = new_window_min; + } + + void next() + { + ++n_shift_; + if (n_shift_ == 8) + { + n_shift_ = 0; + ++current_pos_; + } + + while (current_pos_ < window_max_-buffer_min_) + { + if (buffer_[current_pos_] != 0) // if the current byte has non-zero bits + { + while (n_shift_ != 8) + { + if ((buffer_[current_pos_] & flag8(n_shift_)) != 0) + return; // find 1 bit in the current byte + ++n_shift_; + } + } + n_shift_ = 0; + ++current_pos_; + } + } + bool end() { return !(current_pos_ < window_max_-buffer_min_); } + + int window_size() const { return window_max_ - window_min_; } + size_t buffer_size() const { return buffer_max_ - buffer_min_; } + + VHierarchyNodeHandle node_handle() + { + return VHierarchyNodeHandle(8*(buffer_min_+current_pos_) + (int)n_shift_); + } + + void activate(VHierarchyNodeHandle _node_handle) + { + update_buffer(_node_handle); + buffer_[buffer_idx(_node_handle)] |= flag8(_node_handle); + window_min_ = std::min(window_min_, byte_idx(_node_handle)); + window_max_ = std::max(window_max_, 1+byte_idx(_node_handle)); + } + + + void inactivate(VHierarchyNodeHandle _node_handle) + { + if (is_active(_node_handle) != true) return; + buffer_[buffer_idx(_node_handle)] ^= flag8(_node_handle); + } + + + bool is_active(VHierarchyNodeHandle _node_handle) const + { + if (before_window(_node_handle) == true || + after_window(_node_handle) == true) + return false; + return ((buffer_[buffer_idx(_node_handle)] & flag8(_node_handle)) > 0); + } + + void init(VHierarchyNodeHandleContainer &_roots); + void update_with_vsplit(VHierarchyNodeHandle _parent_handle); + void update_with_ecol(VHierarchyNodeHandle _parent_handle); +}; + +//============================================================================= +} // namespace VDPM +} // namespace OpenMesh +//============================================================================= +#endif // OPENMESH_VDPROGMESH_VHIERARCHYWINDOWS_HH +//============================================================================= + diff --git a/src/OpenMesh/Tools/VDPM/ViewingParameters.cc b/src/OpenMesh/Tools/VDPM/ViewingParameters.cc index f32cb802..ab878b7a 100644 --- a/src/OpenMesh/Tools/VDPM/ViewingParameters.cc +++ b/src/OpenMesh/Tools/VDPM/ViewingParameters.cc @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= // diff --git a/src/OpenMesh/Tools/VDPM/ViewingParameters.hh b/src/OpenMesh/Tools/VDPM/ViewingParameters.hh index a23d8fae..a1ff2f1f 100644 --- a/src/OpenMesh/Tools/VDPM/ViewingParameters.hh +++ b/src/OpenMesh/Tools/VDPM/ViewingParameters.hh @@ -39,12 +39,7 @@ * * * ========================================================================= */ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * * -\*===========================================================================*/ + //============================================================================= diff --git a/src/OpenMesh/Tools/VS2008Tools.vcproj b/src/OpenMesh/Tools/VS2008Tools.vcproj deleted file mode 100644 index e70cf9e9..00000000 --- a/src/OpenMesh/Tools/VS2008Tools.vcproj +++ /dev/null @@ -1,342 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Python/Bindings.cc b/src/Python/Bindings.cc deleted file mode 100644 index 61acd6f4..00000000 --- a/src/Python/Bindings.cc +++ /dev/null @@ -1,152 +0,0 @@ -#include "Python/Bindings.hh" -#include "Python/Vector.hh" -#include "Python/Mesh.hh" -#include "Python/PropertyManager.hh" -#include "Python/InputOutput.hh" -#include "Python/Decimater.hh" - -#include - -namespace OpenMesh { -namespace Python { - -/** - * Expose mesh items to %Python. - */ -void expose_items() { - class_("Vertex"); - class_("Halfedge"); - class_("Edge"); - class_("Face"); -} - -/** - * Expose item and property handles to %Python. - */ -void expose_handles() { - class_("BaseHandle", init >()) - .def("idx", &BaseHandle::idx) - .def("is_valid", &BaseHandle::is_valid) - .def("reset", &BaseHandle::reset) - .def("invalidate", &BaseHandle::invalidate) - .def(self == self) - .def(self != self) - .def(self < self) - ; - - class_ >("VertexHandle", init >()); - class_ >("HalfedgeHandle", init >()); - class_ >("EdgeHandle", init >()); - class_ >("FaceHandle", init >()); - - class_, bases >("BasePropHandle", init >()); - - class_, bases > >("VPropHandle", init >()) - .def(init&>()); - class_, bases > >("HPropHandle", init >()) - .def(init&>()); - class_, bases > >("EPropHandle", init >()) - .def(init&>()); - class_, bases > >("FPropHandle", init >()) - .def(init&>()); - class_, bases > >("MPropHandle", init >()) - .def(init&>()); -} - - -/** - * Expose the StatusBits enum and StatusInfo class to %Python. - */ -void expose_status_bits_and_info() { - using OpenMesh::Attributes::StatusBits; - using OpenMesh::Attributes::StatusInfo; - - enum_("StatusBits") - .value("DELETED", OpenMesh::Attributes::DELETED) - .value("LOCKED", OpenMesh::Attributes::LOCKED) - .value("SELECTED", OpenMesh::Attributes::SELECTED) - .value("HIDDEN", OpenMesh::Attributes::HIDDEN) - .value("FEATURE", OpenMesh::Attributes::FEATURE) - .value("TAGGED", OpenMesh::Attributes::TAGGED) - .value("TAGGED2", OpenMesh::Attributes::TAGGED2) - .value("FIXEDNONMANIFOLD", OpenMesh::Attributes::FIXEDNONMANIFOLD) - .value("UNUSED", OpenMesh::Attributes::UNUSED) - ; - - class_("StatusInfo") - .def("deleted", &StatusInfo::deleted) - .def("set_deleted", &StatusInfo::set_deleted) - .def("locked", &StatusInfo::locked) - .def("set_locked", &StatusInfo::set_locked) - .def("selected", &StatusInfo::selected) - .def("set_selected", &StatusInfo::set_selected) - .def("hidden", &StatusInfo::hidden) - .def("set_hidden", &StatusInfo::set_hidden) - .def("feature", &StatusInfo::feature) - .def("set_feature", &StatusInfo::set_feature) - .def("tagged", &StatusInfo::tagged) - .def("set_tagged", &StatusInfo::set_tagged) - .def("tagged2", &StatusInfo::tagged2) - .def("set_tagged2", &StatusInfo::set_tagged2) - .def("fixed_nonmanifold", &StatusInfo::fixed_nonmanifold) - .def("set_fixed_nonmanifold", &StatusInfo::set_fixed_nonmanifold) - .def("bits", &StatusInfo::bits) - .def("set_bits", &StatusInfo::set_bits) - .def("is_bit_set", &StatusInfo::is_bit_set) - .def("set_bit", &StatusInfo::set_bit) - .def("unset_bit", &StatusInfo::unset_bit) - .def("change_bit", &StatusInfo::change_bit) - ; -} - -BOOST_PYTHON_MODULE(openmesh) { - expose_items(); - expose_handles(); - expose_status_bits_and_info(); - - expose_vec("Vec2f"); - expose_vec("Vec3f"); - expose_vec("Vec4f"); - expose_vec("Vec2d"); - expose_vec("Vec3d"); - expose_vec("Vec4d"); - - expose_mesh("PolyMesh"); - expose_mesh("TriMesh"); - - expose_iterator("VertexIter"); - expose_iterator("HalfedgeIter"); - expose_iterator("EdgeIter"); - expose_iterator("FaceIter"); - - expose_circulator("VertexVertexIter"); - expose_circulator("VertexIHalfedgeIter"); - expose_circulator("VertexOHalfedgeIter"); - expose_circulator("VertexEdgeIter"); - expose_circulator("VertexFaceIter"); - - expose_circulator("FaceVertexIter"); - expose_circulator("FaceHalfedgeIter"); - expose_circulator("FaceEdgeIter"); - expose_circulator("FaceFaceIter"); - - expose_circulator("HalfedgeLoopIter"); - - typedef IteratorWrapperT VertexIterWrapper; - typedef IteratorWrapperT HalfedgeIterWrapper; - typedef IteratorWrapperT EdgeIterWrapper; - typedef IteratorWrapperT FaceIterWrapper; - - expose_property_manager, VertexHandle, VertexIterWrapper>("VPropertyManager"); - expose_property_manager, HalfedgeHandle, HalfedgeIterWrapper>("HPropertyManager"); - expose_property_manager, EdgeHandle, EdgeIterWrapper>("EPropertyManager"); - expose_property_manager, FaceHandle, FaceIterWrapper>("FPropertyManager"); - - expose_io(); - - expose_decimater("PolyMesh"); - expose_decimater("TriMesh"); -} - -} // namespace Python -} // namespace OpenMesh diff --git a/src/Python/Bindings.hh b/src/Python/Bindings.hh deleted file mode 100644 index 0d37cf5c..00000000 --- a/src/Python/Bindings.hh +++ /dev/null @@ -1,48 +0,0 @@ -/** @file */ - -#ifndef OPENMESH_PYTHON_BINDINGS_HH -#define OPENMESH_PYTHON_BINDINGS_HH - -#include -#include -#include -#include - -#include "OpenMesh/Core/IO/MeshIO.hh" -#include "OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh" -#include "OpenMesh/Core/Mesh/PolyMesh_ArrayKernelT.hh" - -using namespace boost::python; - -namespace OpenMesh { - -/** - * This namespace contains classes and functions that are used to expose - * %OpenMesh to %Python. - */ -namespace Python { - -/** - * Return value policy for functions that return references to objects that are - * managed by %OpenMesh. - */ -#define OPENMESH_PYTHON_DEFAULT_POLICY return_value_policy() - -struct MeshTraits : public OpenMesh::DefaultTraits { - /** Use double precision points */ - typedef OpenMesh::Vec3d Point; - - /** Use double precision normals */ - typedef OpenMesh::Vec3d Normal; - - /** Use RGBA colors */ - typedef OpenMesh::Vec4f Color; -}; - -typedef OpenMesh::TriMesh_ArrayKernelT TriMesh; -typedef OpenMesh::PolyMesh_ArrayKernelT PolyMesh; - -} // namespace OpenMesh -} // namespace Python - -#endif diff --git a/src/Python/CMakeLists.txt b/src/Python/CMakeLists.txt deleted file mode 100644 index cafb785b..00000000 --- a/src/Python/CMakeLists.txt +++ /dev/null @@ -1,215 +0,0 @@ -IF(NOT DEFINED OPENMESH_BUILD_PYTHON_BINDINGS) - SET(OPENMESH_BUILD_PYTHON_BINDINGS TRUE CACHE BOOL "Enable or disable building the Python Bindings.") -ENDIF() - -IF(NOT DEFINED OPENMESH_BUILD_PYTHON_UNIT_TESTS) - SET(OPENMESH_BUILD_PYTHON_UNIT_TESTS FALSE CACHE BOOL "Enable or disable building the Python unit tests.") -ENDIF() - -IF(NOT DEFINED OPENMESH_PYTHON_VERSION) - SET(OPENMESH_PYTHON_VERSION "2.7" CACHE STRING "Choose the Python version that is used to build the Python Bindings.") -ENDIF() - -IF(OPENMESH_BUILD_PYTHON_BINDINGS) - # Create log file - SET(PYTHONLOG "${CMAKE_CURRENT_BINARY_DIR}/PythonLog.txt") - FILE(WRITE ${PYTHONLOG} "") - - # Look for the python libs - MESSAGE(STATUS "Looking for PythonLibs") - FIND_PACKAGE(PythonLibs ${OPENMESH_PYTHON_VERSION} QUIET) - - IF(PYTHONLIBS_FOUND) - MESSAGE(STATUS "Looking for PythonLibs -- found") - - # Determine the name of the python component - STRING(REGEX MATCH "^[0-9]+\\.[0-9]+" PYTHON_VERSION_MAJOR_MINOR ${PYTHONLIBS_VERSION_STRING}) - STRING(REGEX REPLACE "\\." "" PYTHON_VERSION_MAJOR_MINOR ${PYTHON_VERSION_MAJOR_MINOR}) - STRING(REGEX MATCH "^[0-9]" PYTHON_VERSION_MAJOR ${PYTHON_VERSION_MAJOR_MINOR}) - - MESSAGE(STATUS "Looking for Boost Python") - - SET(BOOST_PYTHON_COMPONENT_NAMES "python-py${PYTHON_VERSION_MAJOR_MINOR}" "python${PYTHON_VERSION_MAJOR}" "python") - - FOREACH(NAME ${BOOST_PYTHON_COMPONENT_NAMES}) - IF(NOT Boost_FOUND) - FILE(APPEND ${PYTHONLOG} "Looking for component ${NAME}\n") - FIND_PACKAGE(Boost QUIET COMPONENTS ${NAME}) - ENDIF() - ENDFOREACH() - - FILE(APPEND ${PYTHONLOG} "\n") - - IF(Boost_FOUND) - MESSAGE(STATUS "Looking for Boost Python -- found") - MESSAGE(STATUS "Checking the Boost Python configuration") - - SET(CMAKE_TRY_COMPILE_CONFIGURATION "Release") - - TRY_COMPILE( - COMPILE_WORKS - ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/Example/ - Example - CMAKE_FLAGS - "-DINCLUDE_DIRECTORIES:STRING=${PYTHON_INCLUDE_DIRS};${Boost_INCLUDE_DIRS}" - "-DLINK_DIRECTORIES:STRING=${Boost_LIBRARY_DIRS}" - "-DLINK_LIBRARIES:STRING=${PYTHON_LIBRARIES};${Boost_LIBRARIES}" - OUTPUT_VARIABLE OUTPUT_TRY_COMPILE - ) - - FILE(APPEND ${PYTHONLOG} "INCLUDE_DIRECTORIES: ${PYTHON_INCLUDE_DIRS};${Boost_INCLUDE_DIRS}\n") - FILE(APPEND ${PYTHONLOG} "LINK_DIRECTORIES: ${Boost_LIBRARY_DIRS}\n") - FILE(APPEND ${PYTHONLOG} "LINK_LIBRARIES: ${PYTHON_LIBRARIES};${Boost_LIBRARIES}\n\n") - FILE(APPEND ${PYTHONLOG} "${OUTPUT_TRY_COMPILE}") - - IF(COMPILE_WORKS) - # Look for the python interpreter to check if the example works - - # strip version string of any characters (e.g. rc1 # '+') than 0-9 and . - STRING(REGEX REPLACE "(rc[0-9]+)|[^ 0-9 | \\.]" "" PYTHONLIBS_VERSION_STRING_STRIPPED ${PYTHONLIBS_VERSION_STRING}) - FIND_PACKAGE(PythonInterp ${PYTHONLIBS_VERSION_STRING_STRIPPED} QUIET) - - IF(PYTHONINTERP_FOUND) - - IF(MSVC) - SET(PYTHON_WORKING_DIR "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_TRY_COMPILE_CONFIGURATION}") - ELSE() - SET(PYTHON_WORKING_DIR "${CMAKE_CURRENT_BINARY_DIR}") - ENDIF() - - EXECUTE_PROCESS( - COMMAND ${PYTHON_EXECUTABLE} -c "from example import *; greet(); planet = World()" - WORKING_DIRECTORY ${PYTHON_WORKING_DIR} - RESULT_VARIABLE PYTHON_WORKS - OUTPUT_QUIET - ERROR_QUIET - ) - - IF(PYTHON_WORKS EQUAL 0) - - ### EVERYTHING WORKS ### - - MESSAGE(STATUS "Checking the Boost Python configuration -- done") - - IF(${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang" AND ${Boost_VERSION} VERSION_LESS 105600) - MESSAGE("There are known issues with Clang and Boost Python 1.55 and below.") - MESSAGE("Please consider updating Boost Python.") - ENDIF() - - SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/Build/python/) - FILE(MAKE_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}) - - FILE(GLOB SOURCES *.cc *hh) - - INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} ../) - LINK_DIRECTORIES(${Boost_LIBRARY_DIRS}) - - ADD_LIBRARY(openmesh SHARED ${SOURCES}) - - install(TARGETS openmesh DESTINATION ${ACG_PROJECT_LIBDIR}/python ) - - TARGET_LINK_LIBRARIES( - openmesh - OpenMeshCore - OpenMeshTools - ${Boost_LIBRARIES} - ${PYTHON_LIBRARIES} - ) - - SET_TARGET_PROPERTIES( - openmesh - PROPERTIES - PREFIX "" - DEBUG_POSTFIX "" - RELEASE_POSTFIX "" - ) - - IF(APPLE) - SET_TARGET_PROPERTIES(openmesh PROPERTIES SUFFIX ".so") - IF (NOT (CMAKE_MAJOR_VERSION LESS 3)) - SET_TARGET_PROPERTIES(openmesh PROPERTIES MACOSX_RPATH TRUE) - ENDIF() - ENDIF() - - IF(WIN32) - SET_TARGET_PROPERTIES(openmesh PROPERTIES SUFFIX ".pyd") - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj") - - SET(OUTPUTS openmesh.exp openmesh.lib openmesh.pyd) - - FOREACH(FILE ${OUTPUTS}) - ADD_CUSTOM_COMMAND( - TARGET openmesh POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy - ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${FILE} - ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} - ) - ENDFOREACH() - ENDIF() - - IF(OPENMESH_BUILD_PYTHON_UNIT_TESTS) - SET(UNITTEST_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/Python-Unittests/) - - # Copy unit tests - FILE(GLOB UNITTESTS Unittests/*.py) - FOREACH(TEST ${UNITTESTS}) - FILE(COPY ${TEST} DESTINATION ${UNITTEST_OUTPUT_DIRECTORY}) - ENDFOREACH() - - # Copy test files - FILE(GLOB TESTFILES ${PROJECT_SOURCE_DIR}/src/Unittests/TestFiles/*(.off|.obj|.mtl|.stl|.ply|.om)) - FOREACH(FILE ${TESTFILES}) - FILE(COPY ${FILE} DESTINATION ${UNITTEST_OUTPUT_DIRECTORY}) - ENDFOREACH() - - # Copy library - IF(WIN32) - FOREACH(FILE ${OUTPUTS}) - ADD_CUSTOM_COMMAND( - TARGET openmesh POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy - ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${FILE} - ${UNITTEST_OUTPUT_DIRECTORY} - ) - ENDFOREACH() - ELSE() - ADD_CUSTOM_COMMAND( - TARGET openmesh POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy - ${CMAKE_BINARY_DIR}/Build/python/openmesh.so - ${UNITTEST_OUTPUT_DIRECTORY} - ) - ENDIF() - - ADD_TEST( - NAME Python_tests - WORKING_DIRECTORY ${UNITTEST_OUTPUT_DIRECTORY} - COMMAND ${PYTHON_EXECUTABLE} -m unittest discover --verbose - ) - ENDIF() - - ELSE() - MESSAGE("Checking the Boost Python configuration failed!") - MESSAGE("Reason: An error occurred while running a small Boost Python test project.") - MESSAGE("Make sure that your Python and Boost Python libraries match.") - MESSAGE("Skipping Python Bindings.") - ENDIF() - ELSE() - MESSAGE("Checking the Boost Python configuration failed!") - MESSAGE("Reason: Python Interpreter ${PYTHONLIBS_VERSION_STRING} not found.") - MESSAGE("Skipping Python Bindings.") - ENDIF() - ELSE() - MESSAGE("Checking the Boost Python configuration failed!") - MESSAGE("Reason: Building a small Boost Python test project failed.") - MESSAGE("Make sure that your Python and Boost Python libraries match.") - MESSAGE("Skipping Python Bindings.") - ENDIF() - ELSE() - MESSAGE("Boost Python not found! Skipping Python Bindings.") - ENDIF() - ELSE() - MESSAGE("PythonLibs not found! Skipping Python Bindings.") - ENDIF() -ENDIF() diff --git a/src/Python/Circulator.hh b/src/Python/Circulator.hh deleted file mode 100644 index 5a11e4e2..00000000 --- a/src/Python/Circulator.hh +++ /dev/null @@ -1,98 +0,0 @@ -#ifndef OPENMESH_PYTHON_CIRCULATOR_HH -#define OPENMESH_PYTHON_CIRCULATOR_HH - -#include "Python/Bindings.hh" - -namespace OpenMesh { -namespace Python { - -/** - * Wrapper for circulators. - * - * This class template is used to wrap circulators for %Python. It implements - * %Python's iterator protocol (the magic methods \_\_iter\_\_ and - * \_\_next\_\_). - * - * @tparam Circulator A circulator type. - */ -template -class CirculatorWrapperT { - public: - - /** - * Constructor - * - * @param _mesh The mesh that contains the items to iterate over. - * @param _center The handle to the center item. - */ - CirculatorWrapperT(PolyMesh& _mesh, CenterEntityHandle _center) : - circulator_(_mesh, _center) { - } - - /** - * Constructor - * - * @param _mesh The mesh that contains the items to iterate over. - * @param _center The handle to the center item. - */ - CirculatorWrapperT(TriMesh& _mesh, CenterEntityHandle _center) : - circulator_(_mesh, _center) { - } - - /** - * Implementation of %Python's \_\_iter\_\_ magic method. - * - * @return This circulator. - */ - CirculatorWrapperT iter() const { - return *this; - } - - /** - * Implementation of %Python's \_\_next\_\_ magic method. - * - * @return The next item. Raises a %Python StopIteration exception if - * there are no more items. - */ - typename Circulator::value_type next() { - if (circulator_.is_valid()) { - typename Circulator::value_type res = *circulator_; - ++circulator_; - return res; - } - else { - PyErr_SetString(PyExc_StopIteration, "No more data."); - boost::python::throw_error_already_set(); - } - return typename Circulator::value_type(); - } - - private: - Circulator circulator_; -}; - -/** - * Expose a circulator type to %Python. - * - * @tparam Circulator A circulator type. - * - * @param _name The name of the circulator type to be exposed. - * - * @note Circulators are wrapped by CirculatorWrapperT before they are exposed - * to %Python, i.e. they are not exposed directly. This means that circulators - * that are passed from %Python to C++ are instances of CirculatorWrapperT. - */ -template -void expose_circulator(const char *_name) { - class_ >(_name, init()) - .def(init()) - .def("__iter__", &CirculatorWrapperT::iter) - .def("__next__", &CirculatorWrapperT::next) - .def("next", &CirculatorWrapperT::next) - ; -} - -} // namespace OpenMesh -} // namespace Python - -#endif diff --git a/src/Python/Decimater.hh b/src/Python/Decimater.hh deleted file mode 100644 index c0825231..00000000 --- a/src/Python/Decimater.hh +++ /dev/null @@ -1,297 +0,0 @@ -#ifndef OPENMESH_PYTHON_DECIMATER_HH -#define OPENMESH_PYTHON_DECIMATER_HH - -#include "Python/Bindings.hh" -#include "OpenMesh/Tools/Decimater/ModBaseT.hh" -#include "OpenMesh/Tools/Decimater/ModAspectRatioT.hh" -#include "OpenMesh/Tools/Decimater/ModEdgeLengthT.hh" -#include "OpenMesh/Tools/Decimater/ModHausdorffT.hh" -#include "OpenMesh/Tools/Decimater/ModIndependentSetsT.hh" -#include "OpenMesh/Tools/Decimater/ModNormalDeviationT.hh" -#include "OpenMesh/Tools/Decimater/ModNormalFlippingT.hh" -#include "OpenMesh/Tools/Decimater/ModProgMeshT.hh" -#include "OpenMesh/Tools/Decimater/ModQuadricT.hh" -#include "OpenMesh/Tools/Decimater/ModRoundnessT.hh" -#include "OpenMesh/Tools/Decimater/DecimaterT.hh" - -#include - -namespace OpenMesh { -namespace Python { - -#define INIT_MESH_REF init()[with_custodian_and_ward<1,2>()] - -BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(decimate_overloads, decimate, 0, 1) -BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(decimate_to_faces_overloads, decimate_to_faces, 0, 2) -BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(set_max_err_overloads, set_max_err, 1, 2) -BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(set_min_roundness_overloads, set_min_roundness, 1, 2) - - -template -void expose_module_handle(const char *_name) { - class_(_name) - .def("is_valid", &Handle::is_valid) - ; -} - -template -list infolist(Module& _self) { - const typename Module::InfoList& infos = _self.infolist(); - list res; - for (size_t i = 0; i < infos.size(); ++i) { - res.append(infos[i]); - } - return res; -} - -template -void expose_decimater(const char *_name) { - - typedef Decimater::ModBaseT ModBase; - typedef Decimater::ModAspectRatioT ModAspectRatio; - typedef Decimater::ModEdgeLengthT ModEdgeLength; - typedef Decimater::ModHausdorffT ModHausdorff; - typedef Decimater::ModIndependentSetsT ModIndependentSets; - typedef Decimater::ModNormalDeviationT ModNormalDeviation; - typedef Decimater::ModNormalFlippingT ModNormalFlipping; - typedef Decimater::ModProgMeshT ModProgMesh; - typedef Decimater::ModQuadricT ModQuadric; - typedef Decimater::ModRoundnessT ModRoundness; - - typedef Decimater::ModHandleT ModAspectRatioHandle; - typedef Decimater::ModHandleT ModEdgeLengthHandle; - typedef Decimater::ModHandleT ModHausdorffHandle; - typedef Decimater::ModHandleT ModIndependentSetsHandle; - typedef Decimater::ModHandleT ModNormalDeviationHandle; - typedef Decimater::ModHandleT ModNormalFlippingHandle; - typedef Decimater::ModHandleT ModProgMeshHandle; - typedef Decimater::ModHandleT ModQuadricHandle; - typedef Decimater::ModHandleT ModRoundnessHandle; - - typedef Decimater::BaseDecimaterT BaseDecimater; - typedef Decimater::DecimaterT Decimater; - - typedef typename ModProgMesh::Info Info; - typedef std::vector InfoList; - - bool (BaseDecimater::*add1)(ModAspectRatioHandle&) = &Decimater::add; - bool (BaseDecimater::*add2)(ModEdgeLengthHandle&) = &Decimater::add; - bool (BaseDecimater::*add3)(ModHausdorffHandle&) = &Decimater::add; - bool (BaseDecimater::*add4)(ModIndependentSetsHandle&) = &Decimater::add; - bool (BaseDecimater::*add5)(ModNormalDeviationHandle&) = &Decimater::add; - bool (BaseDecimater::*add6)(ModNormalFlippingHandle&) = &Decimater::add; - bool (BaseDecimater::*add7)(ModProgMeshHandle&) = &Decimater::add; - bool (BaseDecimater::*add8)(ModQuadricHandle&) = &Decimater::add; - bool (BaseDecimater::*add9)(ModRoundnessHandle&) = &Decimater::add; - - bool (BaseDecimater::*remove1)(ModAspectRatioHandle&) = &Decimater::remove; - bool (BaseDecimater::*remove2)(ModEdgeLengthHandle&) = &Decimater::remove; - bool (BaseDecimater::*remove3)(ModHausdorffHandle&) = &Decimater::remove; - bool (BaseDecimater::*remove4)(ModIndependentSetsHandle&) = &Decimater::remove; - bool (BaseDecimater::*remove5)(ModNormalDeviationHandle&) = &Decimater::remove; - bool (BaseDecimater::*remove6)(ModNormalFlippingHandle&) = &Decimater::remove; - bool (BaseDecimater::*remove7)(ModProgMeshHandle&) = &Decimater::remove; - bool (BaseDecimater::*remove8)(ModQuadricHandle&) = &Decimater::remove; - bool (BaseDecimater::*remove9)(ModRoundnessHandle&) = &Decimater::remove; - - ModAspectRatio& (BaseDecimater::*module1)(ModAspectRatioHandle&) = &Decimater::module; - ModEdgeLength& (BaseDecimater::*module2)(ModEdgeLengthHandle&) = &Decimater::module; - ModHausdorff& (BaseDecimater::*module3)(ModHausdorffHandle&) = &Decimater::module; - ModIndependentSets& (BaseDecimater::*module4)(ModIndependentSetsHandle&) = &Decimater::module; - ModNormalDeviation& (BaseDecimater::*module5)(ModNormalDeviationHandle&) = &Decimater::module; - ModNormalFlipping& (BaseDecimater::*module6)(ModNormalFlippingHandle&) = &Decimater::module; - ModProgMesh& (BaseDecimater::*module7)(ModProgMeshHandle&) = &Decimater::module; - ModQuadric& (BaseDecimater::*module8)(ModQuadricHandle&) = &Decimater::module; - ModRoundness& (BaseDecimater::*module9)(ModRoundnessHandle&) = &Decimater::module; - - // Decimater - // ---------------------------------------- - - char buffer[64]; - snprintf(buffer, sizeof buffer, "%s%s", _name, "Decimater"); - - class_(buffer, INIT_MESH_REF) - .def("decimate", &Decimater::decimate, decimate_overloads()) - .def("decimate_to", &Decimater::decimate_to) - .def("decimate_to_faces", &Decimater::decimate_to_faces, decimate_to_faces_overloads()) - - .def("initialize", &Decimater::initialize) - .def("is_initialized", &Decimater::is_initialized) - - .def("add", add1) - .def("add", add2) - .def("add", add3) - .def("add", add4) - .def("add", add5) - .def("add", add6) - .def("add", add7) - .def("add", add8) - .def("add", add9) - - .def("remove", remove1) - .def("remove", remove2) - .def("remove", remove3) - .def("remove", remove4) - .def("remove", remove5) - .def("remove", remove6) - .def("remove", remove7) - .def("remove", remove8) - .def("remove", remove9) - - .def("module", module1, return_value_policy()) - .def("module", module2, return_value_policy()) - .def("module", module3, return_value_policy()) - .def("module", module4, return_value_policy()) - .def("module", module5, return_value_policy()) - .def("module", module6, return_value_policy()) - .def("module", module7, return_value_policy()) - .def("module", module8, return_value_policy()) - .def("module", module9, return_value_policy()) - ; - - // ModBase - // ---------------------------------------- - - snprintf(buffer, sizeof buffer, "%s%s", _name, "ModBase"); - - class_(buffer, no_init) - .def("name", &ModBase::name, OPENMESH_PYTHON_DEFAULT_POLICY) - .def("is_binary", &ModBase::is_binary) - .def("set_binary", &ModBase::set_binary) - .def("initialize", &ModBase::initialize) // TODO VIRTUAL - .def("collapse_priority", &ModBase::collapse_priority) // TODO VIRTUAL - .def("preprocess_collapse", &ModBase::preprocess_collapse) // TODO VIRTUAL - .def("postprocess_collapse", &ModBase::postprocess_collapse) // TODO VIRTUAL - .def("set_error_tolerance_factor", &ModBase::set_error_tolerance_factor) // TODO VIRTUAL - ; - - // ModAspectRatio - // ---------------------------------------- - - snprintf(buffer, sizeof buffer, "%s%s", _name, "ModAspectRatio"); - - class_, boost::noncopyable>(buffer, INIT_MESH_REF) - .def("aspect_ratio", &ModAspectRatio::aspect_ratio) - .def("set_aspect_ratio", &ModAspectRatio::set_aspect_ratio) - ; - - snprintf(buffer, sizeof buffer, "%s%s", _name, "ModAspectRatioHandle"); - expose_module_handle(buffer); - - // ModEdgeLength - // ---------------------------------------- - - snprintf(buffer, sizeof buffer, "%s%s", _name, "ModEdgeLength"); - - class_, boost::noncopyable>(buffer, INIT_MESH_REF) - .def("edge_length", &ModEdgeLength::edge_length) - .def("set_edge_length", &ModEdgeLength::set_edge_length) - ; - - snprintf(buffer, sizeof buffer, "%s%s", _name, "ModEdgeLengthHandle"); - expose_module_handle(buffer); - - // ModHausdorff - // ---------------------------------------- - - snprintf(buffer, sizeof buffer, "%s%s", _name, "ModHausdorff"); - - class_, boost::noncopyable>(buffer, INIT_MESH_REF) - .def("tolerance", &ModHausdorff::tolerance) - .def("set_tolerance", &ModHausdorff::set_tolerance) - ; - - snprintf(buffer, sizeof buffer, "%s%s", _name, "ModHausdorffHandle"); - expose_module_handle(buffer); - - // ModIndependentSets - // ---------------------------------------- - - snprintf(buffer, sizeof buffer, "%s%s", _name, "ModIndependentSets"); - - class_, boost::noncopyable>(buffer, INIT_MESH_REF); - - snprintf(buffer, sizeof buffer, "%s%s", _name, "ModIndependentSetsHandle"); - expose_module_handle(buffer); - - // ModNormalDeviation - // ---------------------------------------- - - snprintf(buffer, sizeof buffer, "%s%s", _name, "ModNormalDeviation"); - - class_, boost::noncopyable>(buffer, INIT_MESH_REF) - .def("normal_deviation", &ModNormalDeviation::normal_deviation) - .def("set_normal_deviation", &ModNormalDeviation::set_normal_deviation) - ; - - snprintf(buffer, sizeof buffer, "%s%s", _name, "ModNormalDeviationHandle"); - expose_module_handle(buffer); - - // ModNormalFlipping - // ---------------------------------------- - - snprintf(buffer, sizeof buffer, "%s%s", _name, "ModNormalFlipping"); - - class_, boost::noncopyable>(buffer, INIT_MESH_REF) - .def("max_normal_deviation", &ModNormalFlipping::max_normal_deviation) - .def("set_max_normal_deviation", &ModNormalFlipping::set_max_normal_deviation) - ; - - snprintf(buffer, sizeof buffer, "%s%s", _name, "ModNormalFlippingHandle"); - expose_module_handle(buffer); - - // ModProgMesh - // ---------------------------------------- - - class_("Info", no_init) - .def_readwrite("v0", &Info::v0) - .def_readwrite("v1", &Info::v1) - .def_readwrite("vl", &Info::vl) - .def_readwrite("vr", &Info::vr) - ; - - snprintf(buffer, sizeof buffer, "%s%s", _name, "ModProgMesh"); - - class_, boost::noncopyable>(buffer, INIT_MESH_REF) - .def("pmi", &infolist) - .def("infolist", &infolist) - .def("write", &ModProgMesh::write) - ; - - snprintf(buffer, sizeof buffer, "%s%s", _name, "ModProgMeshHandle"); - expose_module_handle(buffer); - - // ModQuadric - // ---------------------------------------- - - snprintf(buffer, sizeof buffer, "%s%s", _name, "ModQuadric"); - - class_, boost::noncopyable>(buffer, INIT_MESH_REF) - .def("set_max_err", &ModQuadric::set_max_err, set_max_err_overloads()) - .def("unset_max_err", &ModQuadric::unset_max_err) - .def("max_err", &ModQuadric::max_err) - ; - - snprintf(buffer, sizeof buffer, "%s%s", _name, "ModQuadricHandle"); - expose_module_handle(buffer); - - // ModRoundness - // ---------------------------------------- - - snprintf(buffer, sizeof buffer, "%s%s", _name, "ModRoundness"); - - class_, boost::noncopyable>(buffer, INIT_MESH_REF) - .def("set_min_angle", &ModRoundness::set_min_angle) - .def("set_min_roundness", &ModRoundness::set_min_roundness, set_min_roundness_overloads()) - .def("unset_min_roundness", &ModRoundness::unset_min_roundness) - .def("roundness", &ModRoundness::roundness) - ; - - snprintf(buffer, sizeof buffer, "%s%s", _name, "ModRoundnessHandle"); - expose_module_handle(buffer); -} - -} // namespace OpenMesh -} // namespace Python - -#endif diff --git a/src/Python/Example/CMakeLists.txt b/src/Python/Example/CMakeLists.txt deleted file mode 100644 index 03c278ef..00000000 --- a/src/Python/Example/CMakeLists.txt +++ /dev/null @@ -1,30 +0,0 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.6) -PROJECT(Example) - -FILE(GLOB SOURCES *.cc *hh) - -INCLUDE_DIRECTORIES(${INCLUDE_DIRECTORIES}) -LINK_DIRECTORIES(${LINK_DIRECTORIES}) - -ADD_LIBRARY(example SHARED ${SOURCES}) -TARGET_LINK_LIBRARIES(example ${LINK_LIBRARIES}) - -SET_TARGET_PROPERTIES( - example - PROPERTIES - PREFIX "" - DEBUG_POSTFIX "" - RELEASE_POSTFIX "" -) - -IF(APPLE) - SET_TARGET_PROPERTIES(example PROPERTIES SUFFIX ".so") - IF (NOT (CMAKE_MAJOR_VERSION LESS 3)) - SET_TARGET_PROPERTIES(example PROPERTIES MACOSX_RPATH TRUE) - ENDIF() -ENDIF() - -IF(WIN32) - SET_TARGET_PROPERTIES(example PROPERTIES SUFFIX ".pyd") - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj") -ENDIF() diff --git a/src/Python/Example/Example.cc b/src/Python/Example/Example.cc deleted file mode 100644 index ed1f4b81..00000000 --- a/src/Python/Example/Example.cc +++ /dev/null @@ -1,22 +0,0 @@ -#include - -char const * greet() { - return "hello, world"; -} - -struct World { - void set(std::string msg) { this->msg = msg; } - std::string greet() { return msg; } - std::string msg; -}; - -BOOST_PYTHON_MODULE(example) { - using namespace boost::python; - - def("greet", greet); - - class_("World") - .def("greet", &World::greet) - .def("set", &World::set) - ; -} diff --git a/src/Python/InputOutput.hh b/src/Python/InputOutput.hh deleted file mode 100644 index 054452c9..00000000 --- a/src/Python/InputOutput.hh +++ /dev/null @@ -1,115 +0,0 @@ -#ifndef OPENMESH_PYTHON_INPUTOUTPUT_HH -#define OPENMESH_PYTHON_INPUTOUTPUT_HH - -#include "Python/Bindings.hh" - -namespace OpenMesh { -namespace Python { - -const IO::Options::Flag FLAG_DEFAULT = IO::Options::Default; -const IO::Options::Flag FLAG_BINARY = IO::Options::Binary; -const IO::Options::Flag FLAG_MSB = IO::Options::MSB; -const IO::Options::Flag FLAG_LSB = IO::Options::LSB; -const IO::Options::Flag FLAG_SWAP = IO::Options::Swap; -const IO::Options::Flag FLAG_VERTEXNORMAL = IO::Options::VertexNormal; -const IO::Options::Flag FLAG_VERTEXCOLOR = IO::Options::VertexColor; -const IO::Options::Flag FLAG_VERTEXTEXCOORD = IO::Options::VertexTexCoord; -const IO::Options::Flag FLAG_EDGECOLOR = IO::Options::EdgeColor; -const IO::Options::Flag FLAG_FACENORMAL = IO::Options::FaceNormal; -const IO::Options::Flag FLAG_FACECOLOR = IO::Options::FaceColor; -const IO::Options::Flag FLAG_FACETEXCOORD = IO::Options::FaceTexCoord; -const IO::Options::Flag FLAG_COLORALPHA = IO::Options::ColorAlpha; -const IO::Options::Flag FLAG_COLORFLOAT = IO::Options::ColorFloat; - -BOOST_PYTHON_FUNCTION_OVERLOADS(read_mesh_overloads, IO::read_mesh, 3, 4) -BOOST_PYTHON_FUNCTION_OVERLOADS(write_mesh_overloads, IO::write_mesh, 2, 4) - -/** - * Expose the input/output functions and options to Python. - */ -void expose_io() { - - //====================================================================== - // Functions - //====================================================================== - - bool (*read_mesh_poly )(PolyMesh&, const std::string& ) = &IO::read_mesh; - bool (*read_mesh_poly_options)(PolyMesh&, const std::string&, IO::Options&, bool) = &IO::read_mesh; - bool (*read_mesh_tri )(TriMesh&, const std::string& ) = &IO::read_mesh; - bool (*read_mesh_tri_options )(TriMesh&, const std::string&, IO::Options&, bool) = &IO::read_mesh; - - bool (*write_mesh_poly)(const PolyMesh&, const std::string&, IO::Options, std::streamsize) = &IO::write_mesh; - bool (*write_mesh_tri )(const TriMesh&, const std::string&, IO::Options, std::streamsize) = &IO::write_mesh; - - def("read_mesh", read_mesh_poly); - def("read_mesh", read_mesh_poly_options, read_mesh_overloads()); - def("read_mesh", read_mesh_tri); - def("read_mesh", read_mesh_tri_options, read_mesh_overloads()); - - def("write_mesh", write_mesh_poly, write_mesh_overloads()); - def("write_mesh", write_mesh_tri, write_mesh_overloads()); - - //====================================================================== - // Options - //====================================================================== - - scope scope_options = class_("Options") - .def(init()) - .def("cleanup", &IO::Options::cleanup) - .def("clear", &IO::Options::clear) - .def("is_empty", &IO::Options::is_empty) - .def("check", &IO::Options::check) - .def("is_binary", &IO::Options::is_binary) - .def("vertex_has_normal", &IO::Options::vertex_has_normal) - .def("vertex_has_color", &IO::Options::vertex_has_color) - .def("vertex_has_texcoord", &IO::Options::vertex_has_texcoord) - .def("edge_has_color", &IO::Options::edge_has_color) - .def("face_has_normal", &IO::Options::face_has_normal) - .def("face_has_color", &IO::Options::face_has_color) - .def("face_has_texcoord", &IO::Options::face_has_texcoord) - .def("color_has_alpha", &IO::Options::color_has_alpha) - .def("color_is_float", &IO::Options::color_is_float) - - .def(self == self) - .def(self != self) - .def(self -= IO::Options::Flag()) - .def(self += IO::Options::Flag()) - - .def_readonly("Default", &FLAG_DEFAULT) - .def_readonly("Binary", &FLAG_BINARY) - .def_readonly("MSB", &FLAG_MSB) - .def_readonly("LSB", &FLAG_LSB) - .def_readonly("Swap", &FLAG_SWAP) - .def_readonly("VertexNormal", &FLAG_VERTEXNORMAL) - .def_readonly("VertexColor", &FLAG_VERTEXCOLOR) - .def_readonly("VertexTexCoord", &FLAG_VERTEXTEXCOORD) - .def_readonly("EdgeColor", &FLAG_EDGECOLOR) - .def_readonly("FaceNormal", &FLAG_FACENORMAL) - .def_readonly("FaceColor", &FLAG_FACECOLOR) - .def_readonly("FaceTexCoord", &FLAG_FACETEXCOORD) - .def_readonly("ColorAlpha", &FLAG_COLORALPHA) - .def_readonly("ColorFloat", &FLAG_COLORFLOAT) - ; - - enum_("Flag") - .value("Default", IO::Options::Default) - .value("Binary", IO::Options::Binary) - .value("MSB", IO::Options::MSB) - .value("LSB", IO::Options::LSB) - .value("Swap", IO::Options::Swap) - .value("VertexNormal", IO::Options::VertexNormal) - .value("VertexColor", IO::Options::VertexColor) - .value("VertexTexCoord", IO::Options::VertexTexCoord) - .value("EdgeColor", IO::Options::EdgeColor) - .value("FaceNormal", IO::Options::FaceNormal) - .value("FaceColor", IO::Options::FaceColor) - .value("FaceTexCoord", IO::Options::FaceTexCoord) - .value("ColorAlpha", IO::Options::ColorAlpha) - .value("ColorFloat", IO::Options::ColorFloat) - ; -} - -} // namespace OpenMesh -} // namespace Python - -#endif diff --git a/src/Python/Iterator.hh b/src/Python/Iterator.hh deleted file mode 100644 index 848653ad..00000000 --- a/src/Python/Iterator.hh +++ /dev/null @@ -1,121 +0,0 @@ -#ifndef OPENMESH_PYTHON_ITERATOR_HH -#define OPENMESH_PYTHON_ITERATOR_HH - -#include "Python/Bindings.hh" - -namespace OpenMesh { -namespace Python { - -/** - * Wrapper for mesh item iterators. - * - * This class template is used to wrap mesh item iterators for %Python. It - * implements %Python's iterator protocol (the magic methods \_\_iter\_\_ and - * \_\_next\_\_). - * - * @tparam Iterator An iterator type. - * @tparam n_items A member function pointer that points to the mesh function - * that returns the number of items to iterate over (e.g. n_vertices). - */ -template -class IteratorWrapperT { - public: - - /** - * Constructor - * - * @param _mesh The mesh that contains the items to iterate over. - * @param _hnd The handle of the first item to iterate over. - * @param _skip Specifies if deleted/hidden elements are skipped. - */ - IteratorWrapperT(const PolyMesh& _mesh, typename Iterator::value_type _hnd, bool _skip = false) : - mesh_(_mesh), n_items_(n_items), - iterator_(_mesh, _hnd, _skip), - iterator_end_(_mesh, typename Iterator::value_type(int((_mesh.*n_items)()))) { - } - - /** - * Constructor - * - * @param _mesh The mesh that contains the items to iterate over. - * @param _hnd The handle of the first item to iterate over. - * @param _skip Specifies if deleted/hidden elements are skipped. - */ - IteratorWrapperT(const TriMesh& _mesh, typename Iterator::value_type _hnd, bool _skip = false) : - mesh_(_mesh), n_items_(n_items), - iterator_(_mesh, _hnd, _skip), - iterator_end_(_mesh, typename Iterator::value_type(int((_mesh.*n_items)()))) { - } - - /** - * Implementation of %Python's \_\_iter\_\_ magic method. - * - * @return This iterator. - */ - IteratorWrapperT iter() const { - return *this; - } - - /** - * Implementation of %Python's \_\_next\_\_ magic method. - * - * @return The next item. Raises a %Python StopIteration exception if - * there are no more items. - */ - typename Iterator::value_type next() { - if (iterator_ != iterator_end_) { - typename Iterator::value_type res = *iterator_; - ++iterator_; - return res; - } - else { - PyErr_SetString(PyExc_StopIteration, "No more data."); - boost::python::throw_error_already_set(); - } - return typename Iterator::value_type(); - } - - /** - * Implementation of %Python's \_\_len\_\_ magic method. - * - * @return The number of items in the mesh. - */ - unsigned int len() const { - return (mesh_.*n_items_)(); - } - - private: - const OpenMesh::PolyConnectivity& mesh_; - size_t (OpenMesh::ArrayKernel::*n_items_)() const; - Iterator iterator_; - Iterator iterator_end_; -}; - -/** - * Expose an iterator type to %Python. - * - * @tparam Iterator An iterator type. - * @tparam n_items A member function pointer that points to the mesh function - * that returns the number of items to iterate over (e.g. n_vertices). - * - * @param _name The name of the iterator type to be exposed. - * - * @note %Iterators are wrapped by IteratorWrapperT before they are exposed to - * %Python, i.e. they are not exposed directly. This means that iterators - * that are passed from %Python to C++ are instances of IteratorWrapperT. - */ -template -void expose_iterator(const char *_name) { - class_ >(_name, init >()) - .def(init >()) - .def("__iter__", &IteratorWrapperT::iter) - .def("__next__", &IteratorWrapperT::next) - .def("__len__", &IteratorWrapperT::len) - .def("next", &IteratorWrapperT::next) - ; -} - -} // namespace OpenMesh -} // namespace Python - -#endif diff --git a/src/Python/Mesh.hh b/src/Python/Mesh.hh deleted file mode 100644 index 257bd6cf..00000000 --- a/src/Python/Mesh.hh +++ /dev/null @@ -1,931 +0,0 @@ -#ifndef OPENMESH_PYTHON_MESH_HH -#define OPENMESH_PYTHON_MESH_HH - -#include "Python/Bindings.hh" -#include "Python/Iterator.hh" -#include "Python/Circulator.hh" - -#include - -namespace OpenMesh { -namespace Python { - -BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(garbage_collection_overloads, garbage_collection, 0, 3) -BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(add_property_overloads, add_property, 1, 2) - -BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(copy_all_properties_overloads, copy_all_properties, 2, 3) - -BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(delete_vertex_overloads, delete_vertex, 1, 2) -BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(delete_edge_overloads, delete_edge, 1, 2) -BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(delete_face_overloads, delete_face, 1, 2) -BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(is_boundary_overloads, is_boundary, 1, 2) - -BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(find_feature_edges_overloads, find_feature_edges, 0, 1) -BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(update_normal_overloads, update_normal, 1, 2) -BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(update_halfedge_normals_overloads, update_halfedge_normals, 0, 1) -BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(calc_halfedge_normal_overloads, calc_halfedge_normal, 1, 2) - -/** - * Set the status of an item. - * - * @tparam Mesh A mesh type. - * @tparam PropHandle A handle type. - * - * @param _self The mesh instance that is to be used. - * @param _h The handle of the item whose status is to be set. - * @param _info The status to be set. - * - * Depending on @ref OPENMESH_PYTHON_DEFAULT_POLICY, Mesh::status may - * return by value instead of reference. This function ensures that the - * status of an item can be changed nonetheless. - */ -template -void set_status(Mesh& _self, IndexHandle _h, const OpenMesh::Attributes::StatusInfo& _info) { - _self.status(_h) = _info; -} - -/** - * Set the value of a property of an item. - * - * @tparam Mesh A mesh type. - * @tparam PropHandle A property handle type. - * @tparam IndexHandle The appropriate handle type. - * - * @param _self The mesh instance that is to be used. - * @param _ph The property that is to be set. - * @param _h The handle of the item whose property is to be set. - * @param _value The value to be set. - * - * Depending on @ref OPENMESH_PYTHON_DEFAULT_POLICY, Mesh::property may - * return by value instead of reference. This function ensures that the - * property value of an item can be changed nonetheless. - */ -template -void set_property(Mesh& _self, PropHandle _ph, IndexHandle _h, const object& _value) { - _self.property(_ph, _h) = _value; -} - -/** - * Set the value of a mesh property. - * - * @tparam Mesh A mesh type. - * @tparam PropHandle A property handle type. - * - * @param _self The mesh instance that is to be used. - * @param _ph The property that is to be set. - * @param _value The value to be set. - * - * Depending on @ref OPENMESH_PYTHON_DEFAULT_POLICY, Mesh::property may - * return by value instead of reference. This function ensures that the - * property value of an item can be changed nonetheless. - */ -template -void set_property(Mesh& _self, PropHandle _ph, const object& _value) { - _self.property(_ph) = _value; -} - -/** - * Thin wrapper for assign_connectivity. - * - * @tparam Mesh A mesh type. - * @tparam OtherMesh A mesh type. - * - * @param _self The mesh instance that is to be used. - * @param _other The mesh from which the connectivity is to be copied. - */ -template -void assign_connectivity(Mesh& _self, const OtherMesh& _other) { - _self.assign_connectivity(_other); -} - -/** - * Get an iterator. - */ -template -IteratorWrapperT get_iterator(Mesh& _self) { - return IteratorWrapperT(_self, typename Iterator::value_type(0)); -} - -/** - * Get a skipping iterator. - */ -template -IteratorWrapperT get_skipping_iterator(Mesh& _self) { - return IteratorWrapperT(_self, typename Iterator::value_type(0), true); -} - -/** - * Get a circulator. - * - * @tparam Mesh A Mesh type. - * @tparam Circulator A circulator type. - * @tparam CenterEntityHandle The appropriate handle type. - * - * @param _self The mesh instance that is to be used. - * @param _handle The handle of the item to circulate around. - */ -template -CirculatorWrapperT get_circulator(Mesh& _self, CenterEntityHandle _handle) { - return CirculatorWrapperT(_self, _handle); -} - -/** - * Garbage collection using lists instead of vectors to keep track of a set of - * handles. - * - * @tparam Mesh A Mesh type. - * - * @param _self The mesh instance that is to be used. - * @param _vh_to_update The list of vertex handles to be updated. - * @param _hh_to_update The list of halfedge handles to be updated. - * @param _fh_to_update The list of face handles to be updated. - * @param _v Remove deleted vertices? - * @param _e Remove deleted edges? - * @param _f Remove deleted faces? - */ -template -void garbage_collection(Mesh& _self, list& _vh_to_update, list& _hh_to_update, list& _fh_to_update, bool _v = true, bool _e = true, bool _f = true) { - // Convert list of handles to vector of pointers - stl_input_iterator vh_begin(_vh_to_update); - stl_input_iterator vh_end; - std::vector vh_vector; - vh_vector.insert(vh_vector.end(), vh_begin, vh_end); - - // Convert list of handles to vector of pointers - stl_input_iterator hh_begin(_hh_to_update); - stl_input_iterator hh_end; - std::vector hh_vector; - hh_vector.insert(hh_vector.end(), hh_begin, hh_end); - - // Convert list of handles to vector of pointers - stl_input_iterator fh_begin(_fh_to_update); - stl_input_iterator fh_end; - std::vector fh_vector; - fh_vector.insert(fh_vector.end(), fh_begin, fh_end); - - // Call garbage collection - _self.garbage_collection(vh_vector, hh_vector, fh_vector, _v, _e, _f); -} - -/** - * Add a new face from a %Python list of vertex handles. - * - * @tparam Mesh A Mesh type. - * - * @param _self The mesh instance that is to be used. - * @param _vhandles The list of vertex handles. - */ -template -FaceHandle add_face(Mesh& _self, const list& _vhandles) { - stl_input_iterator begin(_vhandles); - stl_input_iterator end; - - std::vector vector; - vector.insert(vector.end(), begin, end); - - return _self.add_face(vector); -} - -/** - * This function template is used to expose mesh member functions that are only - * available for a specific type of mesh (i.e. they are available for polygon - * meshes or triangle meshes, but not both). - * - * @tparam Class A boost::python::class type. - * - * @param _class The boost::python::class instance for which the member - * functions are to be defined. - */ -template -void expose_type_specific_functions(Class& _class) { - // See the template specializations below -} - -/** - * Function template specialization for polygon meshes. - */ -template <> -void expose_type_specific_functions(class_& _class) { - typedef PolyMesh::Scalar Scalar; - typedef PolyMesh::Point Point; - typedef PolyMesh::Normal Normal; - typedef PolyMesh::Color Color; - - FaceHandle (PolyMesh::*add_face_3_vh)(VertexHandle, VertexHandle, VertexHandle ) = &PolyMesh::add_face; - FaceHandle (PolyMesh::*add_face_4_vh)(VertexHandle, VertexHandle, VertexHandle, VertexHandle) = &PolyMesh::add_face; - FaceHandle (*add_face_list)(PolyMesh&, const list&) = &add_face; - - void (PolyMesh::*split_eh_pt)(EdgeHandle, const Point&) = &PolyMesh::split; - void (PolyMesh::*split_eh_vh)(EdgeHandle, VertexHandle) = &PolyMesh::split; - void (PolyMesh::*split_fh_pt)(FaceHandle, const Point&) = &PolyMesh::split; - void (PolyMesh::*split_fh_vh)(FaceHandle, VertexHandle) = &PolyMesh::split; - - Normal (PolyMesh::*calc_face_normal_pt)(const Point&, const Point&, const Point&) const = &PolyMesh::calc_face_normal; - - _class - .def("add_face", add_face_3_vh) - .def("add_face", add_face_4_vh) - .def("add_face", add_face_list) - - .def("split", split_eh_pt) - .def("split", split_eh_vh) - .def("split", split_fh_pt) - .def("split", split_fh_vh) - - .def("split_copy", &PolyMesh::split_copy) - - .def("calc_face_normal", calc_face_normal_pt) - - .def("insert_edge", &PolyMesh::insert_edge) - ; -} - -/** - * Function template specialization for triangle meshes. - */ -template <> -void expose_type_specific_functions(class_& _class) { - typedef TriMesh::Scalar Scalar; - typedef TriMesh::Point Point; - typedef TriMesh::Normal Normal; - typedef TriMesh::Color Color; - - FaceHandle (TriMesh::*add_face_3_vh)(VertexHandle, VertexHandle, VertexHandle) = &TriMesh::add_face; - FaceHandle (*add_face_list)(TriMesh&, const list&) = &add_face; - - VertexHandle (TriMesh::*split_eh_pt)(EdgeHandle, const Point&) = &TriMesh::split; - void (TriMesh::*split_eh_vh)(EdgeHandle, VertexHandle) = &TriMesh::split; - VertexHandle (TriMesh::*split_fh_pt)(FaceHandle, const Point&) = &TriMesh::split; - void (TriMesh::*split_fh_vh)(FaceHandle, VertexHandle) = &TriMesh::split; - - VertexHandle (TriMesh::*split_copy_eh_pt)(EdgeHandle, const Point&) = &TriMesh::split_copy; - void (TriMesh::*split_copy_eh_vh)(EdgeHandle, VertexHandle) = &TriMesh::split_copy; - VertexHandle (TriMesh::*split_copy_fh_pt)(FaceHandle, const Point&) = &TriMesh::split_copy; - void (TriMesh::*split_copy_fh_vh)(FaceHandle, VertexHandle) = &TriMesh::split_copy; - - HalfedgeHandle (TriMesh::*vertex_split_pt)(Point, VertexHandle, VertexHandle, VertexHandle) = &TriMesh::vertex_split; - HalfedgeHandle (TriMesh::*vertex_split_vh)(VertexHandle, VertexHandle, VertexHandle, VertexHandle) = &TriMesh::vertex_split; - - _class - .def("add_face", add_face_3_vh) - .def("add_face", add_face_list) - - .def("split", split_eh_pt) - .def("split", split_eh_vh) - .def("split", split_fh_pt) - .def("split", split_fh_vh) - - .def("split_copy", split_copy_eh_pt) - .def("split_copy", split_copy_eh_vh) - .def("split_copy", split_copy_fh_pt) - .def("split_copy", split_copy_fh_vh) - - .def("opposite_vh", &TriMesh::opposite_vh) - .def("opposite_he_opposite_vh", &TriMesh::opposite_he_opposite_vh) - - .def("vertex_split", vertex_split_pt) - .def("vertex_split", vertex_split_vh) - - .def("is_flip_ok", &TriMesh::is_flip_ok) - .def("flip", &TriMesh::flip) - ; -} - - -/** - * Expose a mesh type to %Python. - * - * @tparam Mesh A mesh type. - * - * @param _name The name of the mesh type to be exposed. - */ -template -void expose_mesh(const char *_name) { - using OpenMesh::Attributes::StatusInfo; - - typedef typename Mesh::Scalar Scalar; - typedef typename Mesh::Point Point; - typedef typename Mesh::Normal Normal; - typedef typename Mesh::Color Color; - - //====================================================================== - // KernelT Function Pointers - //====================================================================== - - // Get the i'th item - VertexHandle (Mesh::*vertex_handle_uint )(unsigned int) const = &Mesh::vertex_handle; - HalfedgeHandle (Mesh::*halfedge_handle_uint)(unsigned int) const = &Mesh::halfedge_handle; - EdgeHandle (Mesh::*edge_handle_uint )(unsigned int) const = &Mesh::edge_handle; - FaceHandle (Mesh::*face_handle_uint )(unsigned int) const = &Mesh::face_handle; - - // Delete items - void (Mesh::*garbage_collection_bools)(bool, bool, bool) = &Mesh::garbage_collection; - void (*garbage_collection_lists_bools)(Mesh&, list&, list&, list&, bool, bool, bool) = &garbage_collection; - - // Vertex connectivity - HalfedgeHandle (Mesh::*halfedge_handle_vh)(VertexHandle) const = &Mesh::halfedge_handle; - HalfedgeHandle (Mesh::*halfedge_handle_fh)(FaceHandle ) const = &Mesh::halfedge_handle; - - // Halfedge connectivity - FaceHandle (Mesh::*face_handle_hh )(HalfedgeHandle) const = &Mesh::face_handle; - HalfedgeHandle (Mesh::*prev_halfedge_handle_hh)(HalfedgeHandle) const = &Mesh::prev_halfedge_handle; - EdgeHandle (Mesh::*edge_handle_hh )(HalfedgeHandle) const = &Mesh::edge_handle; - - // Edge connectivity - HalfedgeHandle (Mesh::*halfedge_handle_eh_uint)(EdgeHandle, unsigned int) const = &Mesh::halfedge_handle; - - // Set halfedge - void (Mesh::*set_halfedge_handle_vh_hh)(VertexHandle, HalfedgeHandle) = &Mesh::set_halfedge_handle; - void (Mesh::*set_halfedge_handle_fh_hh)(FaceHandle, HalfedgeHandle ) = &Mesh::set_halfedge_handle; - - // Handle -> Item - const typename Mesh::Vertex& (Mesh::*vertex )(VertexHandle ) const = &Mesh::vertex; - const typename Mesh::Halfedge& (Mesh::*halfedge)(HalfedgeHandle) const = &Mesh::halfedge; - const typename Mesh::Edge& (Mesh::*edge )(EdgeHandle ) const = &Mesh::edge; - const typename Mesh::Face& (Mesh::*face )(FaceHandle ) const = &Mesh::face; - - // Item -> Handle - VertexHandle (Mesh::*handle_v)(const typename Mesh::Vertex& ) const = &Mesh::handle; - HalfedgeHandle (Mesh::*handle_h)(const typename Mesh::Halfedge&) const = &Mesh::handle; - EdgeHandle (Mesh::*handle_e)(const typename Mesh::Edge& ) const = &Mesh::handle; - FaceHandle (Mesh::*handle_f)(const typename Mesh::Face& ) const = &Mesh::handle; - - // Get value of a standard property (point, normal, color) - const typename Mesh::Point& (Mesh::*point_vh )(VertexHandle ) const = &Mesh::point; - const typename Mesh::Normal& (Mesh::*normal_vh)(VertexHandle ) const = &Mesh::normal; - const typename Mesh::Normal& (Mesh::*normal_hh)(HalfedgeHandle) const = &Mesh::normal; - const typename Mesh::Normal& (Mesh::*normal_fh)(FaceHandle ) const = &Mesh::normal; - const typename Mesh::Color& (Mesh::*color_vh )(VertexHandle ) const = &Mesh::color; - const typename Mesh::Color& (Mesh::*color_hh )(HalfedgeHandle) const = &Mesh::color; - const typename Mesh::Color& (Mesh::*color_eh )(EdgeHandle ) const = &Mesh::color; - const typename Mesh::Color& (Mesh::*color_fh )(FaceHandle ) const = &Mesh::color; - - // Get value of a standard property (texture coordinate) - const typename Mesh::TexCoord1D& (Mesh::*texcoord1D_vh)(VertexHandle ) const = &Mesh::texcoord1D; - const typename Mesh::TexCoord1D& (Mesh::*texcoord1D_hh)(HalfedgeHandle) const = &Mesh::texcoord1D; - const typename Mesh::TexCoord2D& (Mesh::*texcoord2D_vh)(VertexHandle ) const = &Mesh::texcoord2D; - const typename Mesh::TexCoord2D& (Mesh::*texcoord2D_hh)(HalfedgeHandle) const = &Mesh::texcoord2D; - const typename Mesh::TexCoord3D& (Mesh::*texcoord3D_vh)(VertexHandle ) const = &Mesh::texcoord3D; - const typename Mesh::TexCoord3D& (Mesh::*texcoord3D_hh)(HalfedgeHandle) const = &Mesh::texcoord3D; - - // Get value of a standard property (status) - const StatusInfo& (Mesh::*status_vh)(VertexHandle ) const = &Mesh::status; - const StatusInfo& (Mesh::*status_hh)(HalfedgeHandle) const = &Mesh::status; - const StatusInfo& (Mesh::*status_eh)(EdgeHandle ) const = &Mesh::status; - const StatusInfo& (Mesh::*status_fh)(FaceHandle ) const = &Mesh::status; - - // Set value of a standard property (point, normal, color) - void (Mesh::*set_normal_vh)(VertexHandle, const typename Mesh::Normal&) = &Mesh::set_normal; - void (Mesh::*set_normal_hh)(HalfedgeHandle, const typename Mesh::Normal&) = &Mesh::set_normal; - void (Mesh::*set_normal_fh)(FaceHandle, const typename Mesh::Normal&) = &Mesh::set_normal; - void (Mesh::*set_color_vh )(VertexHandle, const typename Mesh::Color& ) = &Mesh::set_color; - void (Mesh::*set_color_hh )(HalfedgeHandle, const typename Mesh::Color& ) = &Mesh::set_color; - void (Mesh::*set_color_eh )(EdgeHandle, const typename Mesh::Color& ) = &Mesh::set_color; - void (Mesh::*set_color_fh )(FaceHandle, const typename Mesh::Color& ) = &Mesh::set_color; - - // Set value of a standard property (texture coordinate) - void (Mesh::*set_texcoord1D_vh)(VertexHandle, const typename Mesh::TexCoord1D&) = &Mesh::set_texcoord1D; - void (Mesh::*set_texcoord1D_hh)(HalfedgeHandle, const typename Mesh::TexCoord1D&) = &Mesh::set_texcoord1D; - void (Mesh::*set_texcoord2D_vh)(VertexHandle, const typename Mesh::TexCoord2D&) = &Mesh::set_texcoord2D; - void (Mesh::*set_texcoord2D_hh)(HalfedgeHandle, const typename Mesh::TexCoord2D&) = &Mesh::set_texcoord2D; - void (Mesh::*set_texcoord3D_vh)(VertexHandle, const typename Mesh::TexCoord3D&) = &Mesh::set_texcoord3D; - void (Mesh::*set_texcoord3D_hh)(HalfedgeHandle, const typename Mesh::TexCoord3D&) = &Mesh::set_texcoord3D; - - // Set value of a standard property (status) - void (*set_status_vh)(Mesh&, VertexHandle, const StatusInfo&) = &set_status; - void (*set_status_hh)(Mesh&, HalfedgeHandle, const StatusInfo&) = &set_status; - void (*set_status_eh)(Mesh&, EdgeHandle, const StatusInfo&) = &set_status; - void (*set_status_fh)(Mesh&, FaceHandle, const StatusInfo&) = &set_status; - - // Property management - add property - void (Mesh::*add_property_vph)(VPropHandleT&, const std::string&) = &Mesh::add_property; - void (Mesh::*add_property_eph)(EPropHandleT&, const std::string&) = &Mesh::add_property; - void (Mesh::*add_property_hph)(HPropHandleT&, const std::string&) = &Mesh::add_property; - void (Mesh::*add_property_fph)(FPropHandleT&, const std::string&) = &Mesh::add_property; - void (Mesh::*add_property_mph)(MPropHandleT&, const std::string&) = &Mesh::add_property; - - // Property management - remove property - void (Mesh::*remove_property_vph)(VPropHandleT&) = &Mesh::remove_property; - void (Mesh::*remove_property_eph)(EPropHandleT&) = &Mesh::remove_property; - void (Mesh::*remove_property_hph)(HPropHandleT&) = &Mesh::remove_property; - void (Mesh::*remove_property_fph)(FPropHandleT&) = &Mesh::remove_property; - void (Mesh::*remove_property_mph)(MPropHandleT&) = &Mesh::remove_property; - - // Property management - get property by name - bool (Mesh::*get_property_handle_vph)(VPropHandleT&, const std::string&) const = &Mesh::get_property_handle; - bool (Mesh::*get_property_handle_eph)(EPropHandleT&, const std::string&) const = &Mesh::get_property_handle; - bool (Mesh::*get_property_handle_hph)(HPropHandleT&, const std::string&) const = &Mesh::get_property_handle; - bool (Mesh::*get_property_handle_fph)(FPropHandleT&, const std::string&) const = &Mesh::get_property_handle; - bool (Mesh::*get_property_handle_mph)(MPropHandleT&, const std::string&) const = &Mesh::get_property_handle; - - // Property management - get property value for an item - const object& (Mesh::*property_vertex )(VPropHandleT, VertexHandle ) const = &Mesh::property; - const object& (Mesh::*property_edge )(EPropHandleT, EdgeHandle ) const = &Mesh::property; - const object& (Mesh::*property_halfedge)(HPropHandleT, HalfedgeHandle) const = &Mesh::property; - const object& (Mesh::*property_face )(FPropHandleT, FaceHandle ) const = &Mesh::property; - const object& (Mesh::*property_mesh )(MPropHandleT ) const = &Mesh::property; - - // Property management - set property value for an item - void (*set_property_vertex )(Mesh&, VPropHandleT, VertexHandle, const object&) = &set_property; - void (*set_property_edge )(Mesh&, EPropHandleT, EdgeHandle, const object&) = &set_property; - void (*set_property_halfedge)(Mesh&, HPropHandleT, HalfedgeHandle, const object&) = &set_property; - void (*set_property_face )(Mesh&, FPropHandleT, FaceHandle, const object&) = &set_property; - void (*set_property_mesh )(Mesh&, MPropHandleT, const object&) = &set_property; - - // Low-level adding new items - VertexHandle (Mesh::*new_vertex_void )(void ) = &Mesh::new_vertex; - VertexHandle (Mesh::*new_vertex_point)(const typename Mesh::Point& ) = &Mesh::new_vertex; - FaceHandle (Mesh::*new_face_void )(void ) = &Mesh::new_face; - FaceHandle (Mesh::*new_face_face )(const typename Mesh::Face& ) = &Mesh::new_face; - - // Kernel item iterators - IteratorWrapperT (*vertices )(Mesh&) = &get_iterator; - IteratorWrapperT (*halfedges)(Mesh&) = &get_iterator; - IteratorWrapperT (*edges )(Mesh&) = &get_iterator; - IteratorWrapperT (*faces )(Mesh&) = &get_iterator; - - IteratorWrapperT (*svertices )(Mesh&) = &get_skipping_iterator; - IteratorWrapperT (*shalfedges)(Mesh&) = &get_skipping_iterator; - IteratorWrapperT (*sedges )(Mesh&) = &get_skipping_iterator; - IteratorWrapperT (*sfaces )(Mesh&) = &get_skipping_iterator; - - //====================================================================== - // BaseKernel Function Pointers - //====================================================================== - - // Copy property - void (Mesh::*copy_property_vprop)(VPropHandleT&, VertexHandle, VertexHandle ) = &Mesh::copy_property; - void (Mesh::*copy_property_hprop)(HPropHandleT, HalfedgeHandle, HalfedgeHandle) = &Mesh::copy_property; - void (Mesh::*copy_property_eprop)(EPropHandleT, EdgeHandle, EdgeHandle ) = &Mesh::copy_property; - void (Mesh::*copy_property_fprop)(FPropHandleT, FaceHandle, FaceHandle ) = &Mesh::copy_property; - - // Copy all properties - void (Mesh::*copy_all_properties_vh_vh_bool)(VertexHandle, VertexHandle, bool) = &Mesh::copy_all_properties; - void (Mesh::*copy_all_properties_hh_hh_bool)(HalfedgeHandle, HalfedgeHandle, bool) = &Mesh::copy_all_properties; - void (Mesh::*copy_all_properties_eh_eh_bool)(EdgeHandle, EdgeHandle, bool) = &Mesh::copy_all_properties; - void (Mesh::*copy_all_properties_fh_fh_bool)(FaceHandle, FaceHandle, bool) = &Mesh::copy_all_properties; - - //====================================================================== - // PolyConnectivity Function Pointers - //====================================================================== - - // Assign connectivity - void (*assign_connectivity_poly)(Mesh&, const PolyMesh&) = &assign_connectivity; - void (*assign_connectivity_tri )(Mesh&, const TriMesh& ) = &assign_connectivity; - - // Vertex and face valence - unsigned int (Mesh::*valence_vh)(VertexHandle) const = &Mesh::valence; - unsigned int (Mesh::*valence_fh)(FaceHandle ) const = &Mesh::valence; - - // Triangulate face or mesh - void (Mesh::*triangulate_fh )(FaceHandle) = &Mesh::triangulate; - void (Mesh::*triangulate_void)( ) = &Mesh::triangulate; - - // Deleting mesh items and other connectivity/topology modifications - void (Mesh::*delete_vertex)(VertexHandle, bool) = &Mesh::delete_vertex; - void (Mesh::*delete_edge )(EdgeHandle, bool) = &Mesh::delete_edge; - void (Mesh::*delete_face )(FaceHandle, bool) = &Mesh::delete_face; - - // Vertex and Face circulators - CirculatorWrapperT (*vv )(Mesh&, VertexHandle ) = &get_circulator; - CirculatorWrapperT (*vih)(Mesh&, VertexHandle ) = &get_circulator; - CirculatorWrapperT (*voh)(Mesh&, VertexHandle ) = &get_circulator; - CirculatorWrapperT (*ve )(Mesh&, VertexHandle ) = &get_circulator; - CirculatorWrapperT (*vf )(Mesh&, VertexHandle ) = &get_circulator; - CirculatorWrapperT (*fv )(Mesh&, FaceHandle ) = &get_circulator; - CirculatorWrapperT (*fh )(Mesh&, FaceHandle ) = &get_circulator; - CirculatorWrapperT (*fe )(Mesh&, FaceHandle ) = &get_circulator; - CirculatorWrapperT (*ff )(Mesh&, FaceHandle ) = &get_circulator; - CirculatorWrapperT (*hl )(Mesh&, HalfedgeHandle) = &get_circulator; - - // Boundary and manifold tests - bool (Mesh::*is_boundary_hh)(HalfedgeHandle ) const = &Mesh::is_boundary; - bool (Mesh::*is_boundary_eh)(EdgeHandle ) const = &Mesh::is_boundary; - bool (Mesh::*is_boundary_vh)(VertexHandle ) const = &Mesh::is_boundary; - bool (Mesh::*is_boundary_fh)(FaceHandle, bool) const = &Mesh::is_boundary; - - // Generic handle derefertiation - const typename Mesh::Vertex& (Mesh::*deref_vh)(VertexHandle ) const = &Mesh::deref; - const typename Mesh::Halfedge& (Mesh::*deref_hh)(HalfedgeHandle) const = &Mesh::deref; - const typename Mesh::Edge& (Mesh::*deref_eh)(EdgeHandle ) const = &Mesh::deref; - const typename Mesh::Face& (Mesh::*deref_fh)(FaceHandle ) const = &Mesh::deref; - - //====================================================================== - // PolyMeshT Function Pointers - //====================================================================== - - void (Mesh::*calc_edge_vector_eh_normal)(EdgeHandle, Normal&) const = &Mesh::calc_edge_vector; - void (Mesh::*calc_edge_vector_hh_normal)(HalfedgeHandle, Normal&) const = &Mesh::calc_edge_vector; - - Normal (Mesh::*calc_edge_vector_eh)(EdgeHandle ) const = &Mesh::calc_edge_vector; - Normal (Mesh::*calc_edge_vector_hh)(HalfedgeHandle) const = &Mesh::calc_edge_vector; - - Scalar (Mesh::*calc_edge_length_eh)(EdgeHandle ) const = &Mesh::calc_edge_length; - Scalar (Mesh::*calc_edge_length_hh)(HalfedgeHandle) const = &Mesh::calc_edge_length; - - Scalar (Mesh::*calc_edge_sqr_length_eh)(EdgeHandle ) const = &Mesh::calc_edge_sqr_length; - Scalar (Mesh::*calc_edge_sqr_length_hh)(HalfedgeHandle) const = &Mesh::calc_edge_sqr_length; - - Scalar (Mesh::*calc_dihedral_angle_fast_hh)(HalfedgeHandle) const = &Mesh::calc_dihedral_angle_fast; - Scalar (Mesh::*calc_dihedral_angle_fast_eh)(EdgeHandle ) const = &Mesh::calc_dihedral_angle_fast; - - Scalar (Mesh::*calc_dihedral_angle_hh)(HalfedgeHandle) const = &Mesh::calc_dihedral_angle; - Scalar (Mesh::*calc_dihedral_angle_eh)(EdgeHandle ) const = &Mesh::calc_dihedral_angle; - - unsigned int (Mesh::*find_feature_edges)(Scalar) = &Mesh::find_feature_edges; - - void (Mesh::*split_fh_vh)(FaceHandle, VertexHandle) = &Mesh::split; - void (Mesh::*split_eh_vh)(EdgeHandle, VertexHandle) = &Mesh::split; - - void (Mesh::*update_normal_fh)(FaceHandle ) = &Mesh::update_normal; - void (Mesh::*update_normal_hh)(HalfedgeHandle, double) = &Mesh::update_normal; - void (Mesh::*update_normal_vh)(VertexHandle ) = &Mesh::update_normal; - - void (Mesh::*update_halfedge_normals)(double) = &Mesh::update_halfedge_normals; - - Normal (Mesh::*calc_face_normal )(FaceHandle ) const = &Mesh::calc_face_normal; - Normal (Mesh::*calc_halfedge_normal)(HalfedgeHandle, double) const = &Mesh::calc_halfedge_normal; - - void (Mesh::*calc_face_centroid_fh_point)(FaceHandle, Point&) const = &Mesh::calc_face_centroid; - Point (Mesh::*calc_face_centroid_fh )(FaceHandle ) const = &Mesh::calc_face_centroid; - - //====================================================================== - // Mesh Type - //====================================================================== - - class_ class_mesh(_name); - - class_mesh - - //====================================================================== - // KernelT - //====================================================================== - - .def("reserve", &Mesh::reserve) - - .def("vertex", vertex, return_value_policy()) - .def("halfedge", halfedge, return_value_policy()) - .def("edge", edge, return_value_policy()) - .def("face", face, return_value_policy()) - - .def("handle", handle_v) - .def("handle", handle_h) - .def("handle", handle_e) - .def("handle", handle_f) - - .def("vertex_handle", vertex_handle_uint) - .def("halfedge_handle", halfedge_handle_uint) - .def("edge_handle", edge_handle_uint) - .def("face_handle", face_handle_uint) - - .def("clear", &Mesh::clear) - .def("clean", &Mesh::clean) - .def("garbage_collection", garbage_collection_bools, garbage_collection_overloads()) - .def("garbage_collection", garbage_collection_lists_bools) - - .def("n_vertices", &Mesh::n_vertices) - .def("n_halfedges", &Mesh::n_halfedges) - .def("n_edges", &Mesh::n_edges) - .def("n_faces", &Mesh::n_faces) - .def("vertices_empty", &Mesh::vertices_empty) - .def("halfedges_empty", &Mesh::halfedges_empty) - .def("edges_empty", &Mesh::edges_empty) - .def("faces_empty", &Mesh::faces_empty) - - .def("halfedge_handle", halfedge_handle_vh) - .def("set_halfedge_handle", set_halfedge_handle_vh_hh) - - .def("to_vertex_handle", &Mesh::to_vertex_handle) - .def("from_vertex_handle", &Mesh::from_vertex_handle) - .def("set_vertex_handle", &Mesh::set_vertex_handle) - .def("face_handle", face_handle_hh) - .def("set_face_handle", &Mesh::set_face_handle) - .def("next_halfedge_handle", &Mesh::next_halfedge_handle) - .def("set_next_halfedge_handle", &Mesh::set_next_halfedge_handle) - .def("prev_halfedge_handle", prev_halfedge_handle_hh) - .def("opposite_halfedge_handle", &Mesh::opposite_halfedge_handle) - .def("ccw_rotated_halfedge_handle", &Mesh::ccw_rotated_halfedge_handle) - .def("cw_rotated_halfedge_handle", &Mesh::cw_rotated_halfedge_handle) - .def("edge_handle", edge_handle_hh) - - .def("halfedge_handle", halfedge_handle_eh_uint) - - .def("halfedge_handle", halfedge_handle_fh) - .def("set_halfedge_handle", set_halfedge_handle_fh_hh) - - .def("point", point_vh, OPENMESH_PYTHON_DEFAULT_POLICY) - .def("set_point", &Mesh::set_point) - .def("normal", normal_vh, OPENMESH_PYTHON_DEFAULT_POLICY) - .def("set_normal", set_normal_vh) - .def("normal", normal_hh, OPENMESH_PYTHON_DEFAULT_POLICY) - .def("set_normal", set_normal_hh) - .def("color", color_vh, OPENMESH_PYTHON_DEFAULT_POLICY) - .def("set_color", set_color_vh) - .def("texcoord1D", texcoord1D_vh, OPENMESH_PYTHON_DEFAULT_POLICY) - .def("set_texcoord1D", set_texcoord1D_vh) - .def("texcoord2D", texcoord2D_vh, OPENMESH_PYTHON_DEFAULT_POLICY) - .def("set_texcoord2D", set_texcoord2D_vh) - .def("texcoord3D", texcoord3D_vh, OPENMESH_PYTHON_DEFAULT_POLICY) - .def("set_texcoord3D", set_texcoord3D_vh) - .def("texcoord1D", texcoord1D_hh, OPENMESH_PYTHON_DEFAULT_POLICY) - .def("set_texcoord1D", set_texcoord1D_hh) - .def("texcoord2D", texcoord2D_hh, OPENMESH_PYTHON_DEFAULT_POLICY) - .def("set_texcoord2D", set_texcoord2D_hh) - .def("texcoord3D", texcoord3D_hh, OPENMESH_PYTHON_DEFAULT_POLICY) - .def("set_texcoord3D", set_texcoord3D_hh) - .def("status", status_vh, OPENMESH_PYTHON_DEFAULT_POLICY) - .def("set_status", set_status_vh) - .def("status", status_hh, OPENMESH_PYTHON_DEFAULT_POLICY) - .def("set_status", set_status_hh) - .def("color", color_hh, OPENMESH_PYTHON_DEFAULT_POLICY) - .def("set_color", set_color_hh) - .def("color", color_eh, OPENMESH_PYTHON_DEFAULT_POLICY) - .def("set_color", set_color_eh) - .def("status", status_eh, OPENMESH_PYTHON_DEFAULT_POLICY) - .def("set_status", set_status_eh) - .def("normal", normal_fh, OPENMESH_PYTHON_DEFAULT_POLICY) - .def("set_normal", set_normal_fh) - .def("color", color_fh, OPENMESH_PYTHON_DEFAULT_POLICY) - .def("set_color", set_color_fh) - .def("status", status_fh, OPENMESH_PYTHON_DEFAULT_POLICY) - .def("set_status", set_status_fh) - - .def("request_vertex_normals", &Mesh::request_vertex_normals) - .def("request_vertex_colors", &Mesh::request_vertex_colors) - .def("request_vertex_texcoords1D", &Mesh::request_vertex_texcoords1D) - .def("request_vertex_texcoords2D", &Mesh::request_vertex_texcoords2D) - .def("request_vertex_texcoords3D", &Mesh::request_vertex_texcoords3D) - .def("request_vertex_status", &Mesh::request_vertex_status) - .def("request_halfedge_status", &Mesh::request_halfedge_status) - .def("request_halfedge_normals", &Mesh::request_halfedge_normals) - .def("request_halfedge_colors", &Mesh::request_halfedge_colors) - .def("request_halfedge_texcoords1D", &Mesh::request_halfedge_texcoords1D) - .def("request_halfedge_texcoords2D", &Mesh::request_halfedge_texcoords2D) - .def("request_halfedge_texcoords3D", &Mesh::request_halfedge_texcoords3D) - .def("request_edge_status", &Mesh::request_edge_status) - .def("request_edge_colors", &Mesh::request_edge_colors) - .def("request_face_normals", &Mesh::request_face_normals) - .def("request_face_colors", &Mesh::request_face_colors) - .def("request_face_status", &Mesh::request_face_status) - .def("request_face_texture_index", &Mesh::request_face_texture_index) - - .def("release_vertex_normals", &Mesh::release_vertex_normals) - .def("release_vertex_colors", &Mesh::release_vertex_colors) - .def("release_vertex_texcoords1D", &Mesh::release_vertex_texcoords1D) - .def("release_vertex_texcoords2D", &Mesh::release_vertex_texcoords2D) - .def("release_vertex_texcoords3D", &Mesh::release_vertex_texcoords3D) - .def("release_vertex_status", &Mesh::release_vertex_status) - .def("release_halfedge_status", &Mesh::release_halfedge_status) - .def("release_halfedge_normals", &Mesh::release_halfedge_normals) - .def("release_halfedge_colors", &Mesh::release_halfedge_colors) - .def("release_halfedge_texcoords1D", &Mesh::release_halfedge_texcoords1D) - .def("release_halfedge_texcoords2D", &Mesh::release_halfedge_texcoords2D) - .def("release_halfedge_texcoords3D", &Mesh::release_halfedge_texcoords3D) - .def("release_edge_status", &Mesh::release_edge_status) - .def("release_edge_colors", &Mesh::release_edge_colors) - .def("release_face_normals", &Mesh::release_face_normals) - .def("release_face_colors", &Mesh::release_face_colors) - .def("release_face_status", &Mesh::release_face_status) - .def("release_face_texture_index", &Mesh::release_face_texture_index) - - .def("has_vertex_normals", &Mesh::has_vertex_normals) - .def("has_vertex_colors", &Mesh::has_vertex_colors) - .def("has_vertex_texcoords1D", &Mesh::has_vertex_texcoords1D) - .def("has_vertex_texcoords2D", &Mesh::has_vertex_texcoords2D) - .def("has_vertex_texcoords3D", &Mesh::has_vertex_texcoords3D) - .def("has_vertex_status", &Mesh::has_vertex_status) - .def("has_halfedge_status", &Mesh::has_halfedge_status) - .def("has_halfedge_normals", &Mesh::has_halfedge_normals) - .def("has_halfedge_colors", &Mesh::has_halfedge_colors) - .def("has_halfedge_texcoords1D", &Mesh::has_halfedge_texcoords1D) - .def("has_halfedge_texcoords2D", &Mesh::has_halfedge_texcoords2D) - .def("has_halfedge_texcoords3D", &Mesh::has_halfedge_texcoords3D) - .def("has_edge_status", &Mesh::has_edge_status) - .def("has_edge_colors", &Mesh::has_edge_colors) - .def("has_face_normals", &Mesh::has_face_normals) - .def("has_face_colors", &Mesh::has_face_colors) - .def("has_face_status", &Mesh::has_face_status) - .def("has_face_texture_index", &Mesh::has_face_texture_index) - - .def("add_property", add_property_vph, add_property_overloads()) - .def("add_property", add_property_eph, add_property_overloads()) - .def("add_property", add_property_hph, add_property_overloads()) - .def("add_property", add_property_fph, add_property_overloads()) - .def("add_property", add_property_mph, add_property_overloads()) - - .def("remove_property", remove_property_vph) - .def("remove_property", remove_property_eph) - .def("remove_property", remove_property_hph) - .def("remove_property", remove_property_fph) - .def("remove_property", remove_property_mph) - - .def("get_property_handle", get_property_handle_vph) - .def("get_property_handle", get_property_handle_eph) - .def("get_property_handle", get_property_handle_hph) - .def("get_property_handle", get_property_handle_fph) - .def("get_property_handle", get_property_handle_mph) - - .def("property", property_vertex, OPENMESH_PYTHON_DEFAULT_POLICY) - .def("property", property_edge, OPENMESH_PYTHON_DEFAULT_POLICY) - .def("property", property_halfedge, OPENMESH_PYTHON_DEFAULT_POLICY) - .def("property", property_face, OPENMESH_PYTHON_DEFAULT_POLICY) - .def("property", property_mesh, OPENMESH_PYTHON_DEFAULT_POLICY) - - .def("set_property", set_property_vertex) - .def("set_property", set_property_edge) - .def("set_property", set_property_halfedge) - .def("set_property", set_property_face) - .def("set_property", set_property_mesh) - - .def("new_vertex", new_vertex_void) - .def("new_vertex", new_vertex_point) - .def("new_edge", &Mesh::new_edge) - .def("new_face", new_face_void) - .def("new_face", new_face_face) - - .def("vertices", vertices) - .def("halfedges", halfedges) - .def("edges", edges) - .def("faces", faces) - - .def("svertices", svertices) - .def("shalfedges", shalfedges) - .def("sedges", sedges) - .def("sfaces", sfaces) - - //====================================================================== - // BaseKernel - //====================================================================== - - .def("copy_property", copy_property_vprop) - .def("copy_property", copy_property_hprop) - .def("copy_property", copy_property_eprop) - .def("copy_property", copy_property_fprop) - - .def("copy_all_properties", copy_all_properties_vh_vh_bool, copy_all_properties_overloads()) - .def("copy_all_properties", copy_all_properties_hh_hh_bool, copy_all_properties_overloads()) - .def("copy_all_properties", copy_all_properties_eh_eh_bool, copy_all_properties_overloads()) - .def("copy_all_properties", copy_all_properties_fh_fh_bool, copy_all_properties_overloads()) - - //====================================================================== - // PolyConnectivity - //====================================================================== - - .def("assign_connectivity", assign_connectivity_poly) - .def("assign_connectivity", assign_connectivity_tri) - - .def("opposite_face_handle", &Mesh::opposite_face_handle) - .def("adjust_outgoing_halfedge", &Mesh::adjust_outgoing_halfedge) - .def("find_halfedge", &Mesh::find_halfedge) - .def("valence", valence_vh) - .def("valence", valence_fh) - .def("collapse", &Mesh::collapse) - .def("is_simple_link", &Mesh::is_simple_link) - .def("is_simply_connected", &Mesh::is_simply_connected) - .def("remove_edge", &Mesh::remove_edge) - .def("reinsert_edge", &Mesh::reinsert_edge) - .def("triangulate", triangulate_fh) - .def("triangulate", triangulate_void) - .def("split_edge", &Mesh::split_edge) - .def("split_edge_copy", &Mesh::split_edge_copy) - - .def("add_vertex", &Mesh::add_vertex) - - .def("is_collapse_ok", &Mesh::is_collapse_ok) - .def("delete_vertex", delete_vertex, delete_vertex_overloads()) - .def("delete_edge", delete_edge, delete_edge_overloads()) - .def("delete_face", delete_face, delete_face_overloads()) - - .def("vv", vv) - .def("vih", vih) - .def("voh", voh) - .def("ve", ve) - .def("vf", vf) - - .def("fv", fv) - .def("fh", fh) - .def("fe", fe) - .def("ff", ff) - - .def("hl", hl) - - .def("is_boundary", is_boundary_hh) - .def("is_boundary", is_boundary_eh) - .def("is_boundary", is_boundary_vh) - .def("is_boundary", is_boundary_fh, is_boundary_overloads()) - .def("is_manifold", &Mesh::is_manifold) - - .def("deref", deref_vh, return_value_policy()) - .def("deref", deref_hh, return_value_policy()) - .def("deref", deref_eh, return_value_policy()) - .def("deref", deref_fh, return_value_policy()) - - .def("is_triangles", &Mesh::is_triangles) - .staticmethod("is_triangles") - - .def_readonly("InvalidVertexHandle", &Mesh::InvalidVertexHandle) - .def_readonly("InvalidHalfedgeHandle", &Mesh::InvalidHalfedgeHandle) - .def_readonly("InvalidEdgeHandle", &Mesh::InvalidEdgeHandle) - .def_readonly("InvalidFaceHandle", &Mesh::InvalidFaceHandle) - - //====================================================================== - // PolyMeshT - //====================================================================== - - .def("add_vertex", &Mesh::add_vertex) - - .def("calc_edge_vector", calc_edge_vector_eh_normal) - .def("calc_edge_vector", calc_edge_vector_eh) - .def("calc_edge_vector", calc_edge_vector_hh_normal) - .def("calc_edge_vector", calc_edge_vector_hh) - - .def("calc_edge_length", calc_edge_length_eh) - .def("calc_edge_length", calc_edge_length_hh) - .def("calc_edge_sqr_length", calc_edge_sqr_length_eh) - .def("calc_edge_sqr_length", calc_edge_sqr_length_hh) - - .def("calc_sector_vectors", &Mesh::calc_sector_vectors) - .def("calc_sector_angle", &Mesh::calc_sector_angle) - .def("calc_sector_normal", &Mesh::calc_sector_normal) - .def("calc_sector_area", &Mesh::calc_sector_area) - - .def("calc_dihedral_angle_fast", calc_dihedral_angle_fast_hh) - .def("calc_dihedral_angle_fast", calc_dihedral_angle_fast_eh) - .def("calc_dihedral_angle", calc_dihedral_angle_hh) - .def("calc_dihedral_angle", calc_dihedral_angle_eh) - - .def("find_feature_edges", find_feature_edges, find_feature_edges_overloads()) - - .def("split", split_fh_vh) - .def("split", split_eh_vh) - - .def("update_normals", &Mesh::update_normals) - .def("update_normal", update_normal_fh) - .def("update_face_normals", &Mesh::update_face_normals) - - .def("calc_face_normal", calc_face_normal) - - .def("calc_face_centroid", calc_face_centroid_fh_point) - .def("calc_face_centroid", calc_face_centroid_fh) - - .def("update_normal", update_normal_hh, update_normal_overloads()) - .def("update_halfedge_normals", update_halfedge_normals, update_halfedge_normals_overloads()) - - .def("calc_halfedge_normal", calc_halfedge_normal, calc_halfedge_normal_overloads()) - - .def("is_estimated_feature_edge", &Mesh::is_estimated_feature_edge) - - .def("update_normal", update_normal_vh) - .def("update_vertex_normals", &Mesh::update_vertex_normals) - - .def("calc_vertex_normal", &Mesh::calc_vertex_normal) - .def("calc_vertex_normal_fast", &Mesh::calc_vertex_normal_fast) - .def("calc_vertex_normal_correct", &Mesh::calc_vertex_normal_correct) - .def("calc_vertex_normal_loop", &Mesh::calc_vertex_normal_loop) - - .def("is_polymesh", &Mesh::is_polymesh) - .staticmethod("is_polymesh") - - .def("is_trimesh", &Mesh::is_trimesh) - .staticmethod("is_trimesh") - ; - - expose_type_specific_functions(class_mesh); - - //====================================================================== - // Nested Types - //====================================================================== - - // Enter mesh scope - scope scope_mesh = class_mesh; - - // Point - const boost::python::type_info point_info = type_id(); - const converter::registration * point_registration = converter::registry::query(point_info); - scope_mesh.attr("Point") = handle<>(point_registration->m_class_object); - - // Normal - const boost::python::type_info normal_info = type_id(); - const converter::registration * normal_registration = converter::registry::query(normal_info); - scope_mesh.attr("Normal") = handle<>(normal_registration->m_class_object); - - // Color - const boost::python::type_info color_info = type_id(); - const converter::registration * color_registration = converter::registry::query(color_info); - scope_mesh.attr("Color") = handle<>(color_registration->m_class_object); - - // TexCoord2D - const boost::python::type_info texcoord2d_info = type_id(); - const converter::registration * texcoord2d_registration = converter::registry::query(texcoord2d_info); - scope_mesh.attr("TexCoord2D") = handle<>(texcoord2d_registration->m_class_object); - - // TexCoord3D - const boost::python::type_info texcoord3d_info = type_id(); - const converter::registration * texcoord3d_registration = converter::registry::query(texcoord3d_info); - scope_mesh.attr("TexCoord3D") = handle<>(texcoord3d_registration->m_class_object); -} - -} // namespace OpenMesh -} // namespace Python - -#endif diff --git a/src/Python/PropertyManager.hh b/src/Python/PropertyManager.hh deleted file mode 100644 index 3fe21f02..00000000 --- a/src/Python/PropertyManager.hh +++ /dev/null @@ -1,143 +0,0 @@ -#ifndef OPENMESH_PYTHON_PROPERTYMANAGER_HH -#define OPENMESH_PYTHON_PROPERTYMANAGER_HH - -#include "Python/Bindings.hh" -#include "OpenMesh/Core/Utils/PropertyManager.hh" - -namespace OpenMesh { -namespace Python { - -BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(retain_overloads, retain, 0, 1) - -/** - * Implementation of %Python's \_\_getitem\_\_ magic method. - * - * @tparam PropertyManager A property manager type. - * @tparam IndexHandle The appropriate handle type. - * - * @param _self The property manager instance that is to be used. - * @param _handle The index of the property value to be returned. - * - * @return The requested property value. - */ -template -object propman_get_item(PropertyManager& _self, IndexHandle _handle) { - return _self[_handle]; -} - -/** - * Implementation of %Python's \_\_setitem\_\_ magic method. - * - * @tparam PropertyManager A property manager type. - * @tparam IndexHandle The appropriate handle type. - * - * @param _self The property manager instance that is to be used. - * @param _handle The index of the property value to be set. - * @param _value The property value to be set. - */ -template -void propman_set_item(PropertyManager& _self, IndexHandle _handle, object _value) { - _self[_handle] = _value; -} - -/** - * Conveniently set the property value for an entire range of mesh items - * using a %Python iterator. - * - * @tparam PropertyManager A property manager type. - * @tparam Iterator A %Python iterator type. - * - * @param _self The property manager instance that is to be used. - * @param _it An iterator that iterates over the items in the range. - * @param _value The value the range will be set to. - */ -template -void propman_set_range(PropertyManager& _self, Iterator _it, object _value) { - try { - while (true) { - _self[_it.next()] = _value; - } - } - catch (error_already_set exception) { - // This is expected behavior - PyErr_Clear(); - } -} - -/** - * Thin wrapper for propertyExists. - * - * @tparam PropertyManager A property manager type. - * @tparam Mesh A mesh type. - * - * @param _mesh The mesh that is used to check if the property exists. - * @param _propname The name of the property. - */ -template -bool property_exists(Mesh& _mesh, const char *_propname) { - return PropertyManager::propertyExists(_mesh, _propname); -} - -/** - * Expose a property manager type to %Python. - * - * This function template is used to expose property managers to %Python. The - * template parameters are used to instantiate the appropriate property manager - * type. - * - * @tparam PropHandle A property handle type (e.g. %VPropHandle\). - * @tparam IndexHandle The appropriate handle type (e.g. %VertexHandle for - * %VPropHandle\). - * @tparam Iterator A %Python iterator type. This type is used to instantiate - * the propman_set_range function. - * - * @param _name The name of the property manager type to be exposed. - */ -template -void expose_property_manager(const char *_name) { - // Convenience typedef - typedef PropertyManager PropertyManager; - - // Function pointers - void (PropertyManager::*retain)(bool) = &PropertyManager::retain; - - object (*getitem)(PropertyManager&, IndexHandle ) = &propman_get_item; - void (*setitem)(PropertyManager&, IndexHandle, object) = &propman_set_item; - - void (*set_range)(PropertyManager&, Iterator, object) = &propman_set_range; - - bool (*property_exists_poly)(PolyMesh&, const char *) = &property_exists; - bool (*property_exists_tri )(TriMesh&, const char *) = &property_exists; - - // Expose property manager - class_(_name) - .def(init >()[with_custodian_and_ward<1,2>()]) - .def(init >()[with_custodian_and_ward<1,2>()]) - - .def("swap", &PropertyManager::swap) - .def("is_valid", &PropertyManager::isValid) - - .def("__bool__", &PropertyManager::operator bool) - .def("__nonzero__", &PropertyManager::operator bool) - - .def("get_raw_property", &PropertyManager::getRawProperty, return_value_policy()) - .def("get_name", &PropertyManager::getName, return_value_policy()) - .def("get_mesh", &PropertyManager::getMesh, return_value_policy()) - - .def("retain", retain, retain_overloads()) - - .def("__getitem__", getitem) - .def("__setitem__", setitem) - - .def("set_range", set_range) - - .def("property_exists", property_exists_poly) - .def("property_exists", property_exists_tri) - .staticmethod("property_exists") - ; -} - -} // namespace OpenMesh -} // namespace Python - -#endif diff --git a/src/Python/Unittests/test_add_face.py b/src/Python/Unittests/test_add_face.py deleted file mode 100644 index f6a6fb20..00000000 --- a/src/Python/Unittests/test_add_face.py +++ /dev/null @@ -1,334 +0,0 @@ -import unittest -import openmesh - -class AddFace(unittest.TestCase): - - def test_add_triangles_to_trimesh(self): - self.mesh = openmesh.TriMesh() - self.vhandle = [] - - # Add some vertices - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 0, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0))) - - # Add two faces - face_vhandles = [] - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[0]) - - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[3]) - - self.mesh.add_face(face_vhandles) - - # Test setup: - # 1 === 2 - # | / | - # | / | - # | / | - # 0 === 3 - - # Check setup - self.assertEqual(self.mesh.n_vertices(), 4) - self.assertEqual(self.mesh.n_faces(), 2) - - def test_add_quad_to_trimesh(self): - self.mesh = openmesh.TriMesh() - self.vhandle = [] - - # Add some vertices - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 0, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0))) - - # Add two faces - face_vhandles = [] - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[3]) - - self.mesh.add_face(face_vhandles) - - # Test setup: - # 1 === 2 - # | / | - # | / | - # | / | - # 0 === 3 - - # Check setup - self.assertEqual(self.mesh.n_vertices(), 4) - self.assertEqual(self.mesh.n_faces(), 2) - - def test_create_triangle_mesh_cube(self): - self.mesh = openmesh.TriMesh() - self.vhandle = [] - - # Add some vertices - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, -1, 1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, -1, 1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, 1, 1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, 1, 1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, -1, -1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, -1, -1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, 1, -1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, 1, -1))) - - # Add six faces to form a cube - face_vhandles = [] - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[3]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[3]) - self.mesh.add_face(face_vhandles) - - #======================= - - face_vhandles = [] - face_vhandles.append(self.vhandle[7]) - face_vhandles.append(self.vhandle[6]) - face_vhandles.append(self.vhandle[5]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - face_vhandles.append(self.vhandle[7]) - face_vhandles.append(self.vhandle[5]) - face_vhandles.append(self.vhandle[4]) - self.mesh.add_face(face_vhandles) - - #======================= - - face_vhandles = [] - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[4]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[4]) - face_vhandles.append(self.vhandle[5]) - self.mesh.add_face(face_vhandles) - - #======================= - - face_vhandles = [] - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[5]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[5]) - face_vhandles.append(self.vhandle[6]) - self.mesh.add_face(face_vhandles) - - #======================= - - face_vhandles = [] - face_vhandles.append(self.vhandle[3]) - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[6]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - face_vhandles.append(self.vhandle[3]) - face_vhandles.append(self.vhandle[6]) - face_vhandles.append(self.vhandle[7]) - self.mesh.add_face(face_vhandles) - - #======================= - - face_vhandles = [] - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[3]) - face_vhandles.append(self.vhandle[7]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[7]) - face_vhandles.append(self.vhandle[4]) - self.mesh.add_face(face_vhandles) - - # Test setup: - # - # 3 ======== 2 - # / /| - # / / | z - # 0 ======== 1 | | - # | | | | y - # | 7 | 6 | / - # | | / | / - # | |/ |/ - # 4 ======== 5 -------> x - - # Check setup - self.assertEqual(self.mesh.n_edges(), 18) - self.assertEqual(self.mesh.n_halfedges(), 36) - self.assertEqual(self.mesh.n_vertices(), 8) - self.assertEqual(self.mesh.n_faces(), 12) - - def test_create_strange_config(self): - self.mesh = openmesh.TriMesh() - self.vhandle = [] - - # 2 x-----------x 1 - # \ / - # \ / - # \ / - # \ / - # \ / - # 0 x ---x 6 - # /|\ | - # / | \ | - # / | \ | - # / | \| - # x----x x - # 3 4 5 - - # Add some vertices - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 0, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 1, 1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, 2, 2))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(3, 3, 3))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(4, 4, 4))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(5, 5, 5))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(6, 6, 6))) - - self.mesh.add_face(self.vhandle[0], self.vhandle[1], self.vhandle[2]) - self.mesh.add_face(self.vhandle[0], self.vhandle[3], self.vhandle[4]) - self.mesh.add_face(self.vhandle[0], self.vhandle[5], self.vhandle[6]) - - # non-manifold! - invalid_fh = self.mesh.add_face(self.vhandle[3], self.vhandle[0], self.vhandle[4]) - - # Check setup - self.assertEqual(self.mesh.n_vertices(), 7) - self.assertEqual(self.mesh.n_faces(), 3) - self.assertEqual(invalid_fh, openmesh.TriMesh.InvalidFaceHandle) - - def test_add_quad_to_polymesh(self): - self.mesh = openmesh.PolyMesh() - self.vhandle = [] - - # Add some vertices - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 0, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0))) - - # Add one face - face_vhandles = [] - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[3]) - - self.mesh.add_face(face_vhandles) - - # Test setup: - # 1 === 2 - # | | - # | | - # | | - # 0 === 3 - - # Check setup - self.assertEqual(self.mesh.n_vertices(), 4) - self.assertEqual(self.mesh.n_faces(), 1) - - def test_create_poly_mesh_cube(self): - self.mesh = openmesh.PolyMesh() - self.vhandle = [] - - # Add some vertices - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, -1, 1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, -1, 1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, 1, 1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, 1, 1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, -1, -1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, -1, -1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, 1, -1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, 1, -1))) - - # Add six faces to form a cube - face_vhandles = [] - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[3]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - face_vhandles.append(self.vhandle[7]) - face_vhandles.append(self.vhandle[6]) - face_vhandles.append(self.vhandle[5]) - face_vhandles.append(self.vhandle[4]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[4]) - face_vhandles.append(self.vhandle[5]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[5]) - face_vhandles.append(self.vhandle[6]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - face_vhandles.append(self.vhandle[3]) - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[6]) - face_vhandles.append(self.vhandle[7]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[3]) - face_vhandles.append(self.vhandle[7]) - face_vhandles.append(self.vhandle[4]) - self.mesh.add_face(face_vhandles) - - # Test setup: - # - # 3 ======== 2 - # / /| - # / / | z - # 0 ======== 1 | | - # | | | | y - # | 7 | 6 | / - # | | / | / - # | |/ |/ - # 4 ======== 5 -------> x - - # Check setup - self.assertEqual(self.mesh.n_edges(), 12) - self.assertEqual(self.mesh.n_halfedges(), 24) - self.assertEqual(self.mesh.n_vertices(), 8) - self.assertEqual(self.mesh.n_faces(), 6) - - -if __name__ == '__main__': - suite = unittest.TestLoader().loadTestsFromTestCase(AddFace) - unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/src/Python/Unittests/test_boundary.py b/src/Python/Unittests/test_boundary.py deleted file mode 100644 index fde5ea35..00000000 --- a/src/Python/Unittests/test_boundary.py +++ /dev/null @@ -1,86 +0,0 @@ -import unittest -import openmesh - -class BoundaryTriangleMesh(unittest.TestCase): - - def setUp(self): - self.mesh = openmesh.TriMesh() - - # Add some vertices - self.vhandle = [] - - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0,-1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2,-1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(3, 0, 0))) - - # Single point - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0,-2, 0))) - - # Add five faces - self.fhandle = [] - - face_vhandles = [] - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[2]) - self.fhandle.append(self.mesh.add_face(face_vhandles)) - - face_vhandles = [] - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[3]) - face_vhandles.append(self.vhandle[4]) - self.fhandle.append(self.mesh.add_face(face_vhandles)) - - face_vhandles = [] - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[3]) - face_vhandles.append(self.vhandle[1]) - self.fhandle.append(self.mesh.add_face(face_vhandles)) - - face_vhandles = [] - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[4]) - self.fhandle.append(self.mesh.add_face(face_vhandles)) - - face_vhandles = [] - face_vhandles.append(self.vhandle[5]) - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[4]) - self.fhandle.append(self.mesh.add_face(face_vhandles)) - - # Test setup: - # 0 ==== 2 - # |\ 0 /|\ - # | \ / | \ - # |2 1 3|4 5 - # | / \ | / - # |/ 1 \|/ - # 3 ==== 4 - # - # Vertex 6 single - - def test_boundary_vertex(self): - self.assertTrue (self.mesh.is_boundary(self.vhandle[0])) - self.assertFalse(self.mesh.is_boundary(self.vhandle[1])) - self.assertTrue (self.mesh.is_boundary(self.vhandle[2])) - self.assertTrue (self.mesh.is_boundary(self.vhandle[3])) - self.assertTrue (self.mesh.is_boundary(self.vhandle[4])) - self.assertTrue (self.mesh.is_boundary(self.vhandle[5])) - - self.assertTrue (self.mesh.is_boundary(self.vhandle[6])) - - def test_boundary_face(self): - self.assertTrue (self.mesh.is_boundary(self.fhandle[0])) - self.assertTrue (self.mesh.is_boundary(self.fhandle[1])) - self.assertTrue (self.mesh.is_boundary(self.fhandle[2])) - self.assertFalse(self.mesh.is_boundary(self.fhandle[3])) - self.assertTrue (self.mesh.is_boundary(self.fhandle[4])) - - -if __name__ == '__main__': - suite = unittest.TestLoader().loadTestsFromTestCase(BoundaryTriangleMesh) - unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/src/Python/Unittests/test_delete_face.py b/src/Python/Unittests/test_delete_face.py deleted file mode 100644 index 5359cfde..00000000 --- a/src/Python/Unittests/test_delete_face.py +++ /dev/null @@ -1,530 +0,0 @@ -import unittest -import openmesh - -class DeleteFaceTriangleMesh(unittest.TestCase): - - def test_delete_half_triangle_mesh_cube_no_edge_status(self): - self.mesh = openmesh.TriMesh() - self.vhandle = [] - - # Add some vertices - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, -1, 1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, -1, 1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, 1, 1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, 1, 1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, -1, -1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, -1, -1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, 1, -1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, 1, -1))) - - # Add six faces to form a cube - face_vhandles = [] - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[3]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[3]) - self.mesh.add_face(face_vhandles) - - #======================= - - face_vhandles = [] - face_vhandles.append(self.vhandle[7]) - face_vhandles.append(self.vhandle[6]) - face_vhandles.append(self.vhandle[5]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - face_vhandles.append(self.vhandle[7]) - face_vhandles.append(self.vhandle[5]) - face_vhandles.append(self.vhandle[4]) - self.mesh.add_face(face_vhandles) - - #======================= - - face_vhandles = [] - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[4]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[4]) - face_vhandles.append(self.vhandle[5]) - self.mesh.add_face(face_vhandles) - - #======================= - - face_vhandles = [] - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[5]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[5]) - face_vhandles.append(self.vhandle[6]) - self.mesh.add_face(face_vhandles) - - #======================= - - face_vhandles = [] - face_vhandles.append(self.vhandle[3]) - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[6]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - face_vhandles.append(self.vhandle[3]) - face_vhandles.append(self.vhandle[6]) - face_vhandles.append(self.vhandle[7]) - self.mesh.add_face(face_vhandles) - - #======================= - - face_vhandles = [] - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[3]) - face_vhandles.append(self.vhandle[7]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[7]) - face_vhandles.append(self.vhandle[4]) - self.mesh.add_face(face_vhandles) - - # Test setup: - # - # 3 ======== 2 - # / /| - # / / | z - # 0 ======== 1 | | - # | | | | y - # | 7 | 6 | / - # | | / | / - # | |/ |/ - # 4 ======== 5 -------> x - - # Check setup - self.assertEqual(self.mesh.n_edges(), 18) - self.assertEqual(self.mesh.n_halfedges(), 36) - self.assertEqual(self.mesh.n_vertices(), 8) - self.assertEqual(self.mesh.n_faces(), 12) - - # ===================================================== - # Now we delete half of the mesh - # ===================================================== - self.mesh.request_face_status() - self.mesh.request_vertex_status() - self.mesh.request_halfedge_status() - - n_face_to_delete = self.mesh.n_faces() / 2 - - # Check the variable - self.assertEqual(n_face_to_delete, 6) - - for i in range(int(n_face_to_delete)): - self.mesh.delete_face(self.mesh.face_handle(i)) - - # ===================================================== - # Check config afterwards - # ===================================================== - - self.assertEqual(self.mesh.n_edges(), 18) - self.assertEqual(self.mesh.n_halfedges(), 36) - self.assertEqual(self.mesh.n_vertices(), 8) - self.assertEqual(self.mesh.n_faces(), 12) - - # ===================================================== - # Cleanup and recheck - # ===================================================== - - self.mesh.garbage_collection() - - self.assertEqual(self.mesh.n_edges(), 18) - self.assertEqual(self.mesh.n_halfedges(), 36) - self.assertEqual(self.mesh.n_vertices(), 8) - self.assertEqual(self.mesh.n_faces(), 6) - - def test_delete_half_triangle_mesh_cube_with_edge_status(self): - self.mesh = openmesh.TriMesh() - self.vhandle = [] - - # Add some vertices - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, -1, 1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, -1, 1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, 1, 1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, 1, 1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, -1, -1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, -1, -1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, 1, -1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, 1, -1))) - - # Add six faces to form a cube - face_vhandles = [] - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[3]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[3]) - self.mesh.add_face(face_vhandles) - - #======================= - - face_vhandles = [] - face_vhandles.append(self.vhandle[7]) - face_vhandles.append(self.vhandle[6]) - face_vhandles.append(self.vhandle[5]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - face_vhandles.append(self.vhandle[7]) - face_vhandles.append(self.vhandle[5]) - face_vhandles.append(self.vhandle[4]) - self.mesh.add_face(face_vhandles) - - #======================= - - face_vhandles = [] - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[4]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[4]) - face_vhandles.append(self.vhandle[5]) - self.mesh.add_face(face_vhandles) - - #======================= - - face_vhandles = [] - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[5]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[5]) - face_vhandles.append(self.vhandle[6]) - self.mesh.add_face(face_vhandles) - - #======================= - - face_vhandles = [] - face_vhandles.append(self.vhandle[3]) - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[6]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - face_vhandles.append(self.vhandle[3]) - face_vhandles.append(self.vhandle[6]) - face_vhandles.append(self.vhandle[7]) - self.mesh.add_face(face_vhandles) - - #======================= - - face_vhandles = [] - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[3]) - face_vhandles.append(self.vhandle[7]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[7]) - face_vhandles.append(self.vhandle[4]) - self.mesh.add_face(face_vhandles) - - # Test setup: - # - # 3 ======== 2 - # / /| - # / / | z - # 0 ======== 1 | | - # | | | | y - # | 7 | 6 | / - # | | / | / - # | |/ |/ - # 4 ======== 5 -------> x - - # Check setup - self.assertEqual(self.mesh.n_edges(), 18) - self.assertEqual(self.mesh.n_halfedges(), 36) - self.assertEqual(self.mesh.n_vertices(), 8) - self.assertEqual(self.mesh.n_faces(), 12) - - # ===================================================== - # Now we delete half of the mesh - # ===================================================== - self.mesh.request_face_status() - self.mesh.request_vertex_status() - self.mesh.request_edge_status() - self.mesh.request_halfedge_status() - - n_face_to_delete = self.mesh.n_faces() / 2 - - # Check the variable - self.assertEqual(n_face_to_delete, 6) - - for i in range(int(n_face_to_delete)): - self.mesh.delete_face(self.mesh.face_handle(i)) - - # ===================================================== - # Check config afterwards - # ===================================================== - - self.assertEqual(self.mesh.n_edges(), 18) - self.assertEqual(self.mesh.n_halfedges(), 36) - self.assertEqual(self.mesh.n_vertices(), 8) - self.assertEqual(self.mesh.n_faces(), 12) - - # ===================================================== - # Cleanup and recheck - # ===================================================== - - self.mesh.garbage_collection() - - self.assertEqual(self.mesh.n_edges(), 13) - self.assertEqual(self.mesh.n_vertices(), 8) - self.assertEqual(self.mesh.n_faces(), 6) - - def test_deletete_half_poly_mesh_cube_without_edge_status(self): - self.mesh = openmesh.PolyMesh() - self.vhandle = [] - - # Add some vertices - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, -1, 1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, -1, 1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, 1, 1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, 1, 1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, -1, -1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, -1, -1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, 1, -1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, 1, -1))) - - # Add six faces to form a cube - face_vhandles = [] - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[3]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - face_vhandles.append(self.vhandle[7]) - face_vhandles.append(self.vhandle[6]) - face_vhandles.append(self.vhandle[5]) - face_vhandles.append(self.vhandle[4]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[4]) - face_vhandles.append(self.vhandle[5]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[5]) - face_vhandles.append(self.vhandle[6]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - face_vhandles.append(self.vhandle[3]) - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[6]) - face_vhandles.append(self.vhandle[7]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[3]) - face_vhandles.append(self.vhandle[7]) - face_vhandles.append(self.vhandle[4]) - self.mesh.add_face(face_vhandles) - - # Test setup: - # - # 3 ======== 2 - # / /| - # / / | z - # 0 ======== 1 | | - # | | | | y - # | 7 | 6 | / - # | | / | / - # | |/ |/ - # 4 ======== 5 -------> x - - # Check setup - self.assertEqual(self.mesh.n_edges(), 12) - self.assertEqual(self.mesh.n_halfedges(), 24) - self.assertEqual(self.mesh.n_vertices(), 8) - self.assertEqual(self.mesh.n_faces(), 6) - - # ===================================================== - # Now we delete half of the mesh - # ===================================================== - self.mesh.request_face_status() - self.mesh.request_vertex_status() - self.mesh.request_halfedge_status() - - n_face_to_delete = self.mesh.n_faces() / 2 - - # Check the variable - self.assertEqual(n_face_to_delete, 3) - - for i in range(int(n_face_to_delete)): - self.mesh.delete_face(self.mesh.face_handle(i)) - - # ===================================================== - # Check config afterwards - # ===================================================== - - self.assertEqual(self.mesh.n_edges(), 12) - self.assertEqual(self.mesh.n_halfedges(), 24) - self.assertEqual(self.mesh.n_vertices(), 8) - self.assertEqual(self.mesh.n_faces(), 6) - - # ===================================================== - # Cleanup and recheck - # ===================================================== - - self.mesh.garbage_collection() - - self.assertEqual(self.mesh.n_edges(), 12) - self.assertEqual(self.mesh.n_halfedges(), 24) - self.assertEqual(self.mesh.n_vertices(), 8) - self.assertEqual(self.mesh.n_faces(), 3) - - def test_deletete_half_poly_mesh_cube_with_edge_status(self): - self.mesh = openmesh.PolyMesh() - self.vhandle = [] - - # Add some vertices - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, -1, 1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, -1, 1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, 1, 1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, 1, 1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, -1, -1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, -1, -1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, 1, -1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, 1, -1))) - - # Add six faces to form a cube - face_vhandles = [] - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[3]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - face_vhandles.append(self.vhandle[7]) - face_vhandles.append(self.vhandle[6]) - face_vhandles.append(self.vhandle[5]) - face_vhandles.append(self.vhandle[4]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[4]) - face_vhandles.append(self.vhandle[5]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[5]) - face_vhandles.append(self.vhandle[6]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - face_vhandles.append(self.vhandle[3]) - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[6]) - face_vhandles.append(self.vhandle[7]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[3]) - face_vhandles.append(self.vhandle[7]) - face_vhandles.append(self.vhandle[4]) - self.mesh.add_face(face_vhandles) - - # Test setup: - # - # 3 ======== 2 - # / /| - # / / | z - # 0 ======== 1 | | - # | | | | y - # | 7 | 6 | / - # | | / | / - # | |/ |/ - # 4 ======== 5 -------> x - - # Check setup - self.assertEqual(self.mesh.n_edges(), 12) - self.assertEqual(self.mesh.n_halfedges(), 24) - self.assertEqual(self.mesh.n_vertices(), 8) - self.assertEqual(self.mesh.n_faces(), 6) - - # ===================================================== - # Now we delete half of the mesh - # ===================================================== - self.mesh.request_face_status() - self.mesh.request_vertex_status() - self.mesh.request_edge_status() - self.mesh.request_halfedge_status() - - n_face_to_delete = self.mesh.n_faces() / 2 - - # Check the variable - self.assertEqual(n_face_to_delete, 3) - - for i in range(int(n_face_to_delete)): - self.mesh.delete_face(self.mesh.face_handle(i)) - - # ===================================================== - # Check config afterwards - # ===================================================== - - self.assertEqual(self.mesh.n_edges(), 12) - self.assertEqual(self.mesh.n_halfedges(), 24) - self.assertEqual(self.mesh.n_vertices(), 8) - self.assertEqual(self.mesh.n_faces(), 6) - - # ===================================================== - # Cleanup and recheck - # ===================================================== - - self.mesh.garbage_collection() - - self.assertEqual(self.mesh.n_edges(), 10) - self.assertEqual(self.mesh.n_halfedges(), 20) - self.assertEqual(self.mesh.n_vertices(), 8) - self.assertEqual(self.mesh.n_faces(), 3) - - -if __name__ == '__main__': - suite = unittest.TestLoader().loadTestsFromTestCase(DeleteFaceTriangleMesh) - unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/src/Python/Unittests/test_property.py b/src/Python/Unittests/test_property.py deleted file mode 100755 index 61d3cbd7..00000000 --- a/src/Python/Unittests/test_property.py +++ /dev/null @@ -1,289 +0,0 @@ -import unittest -import openmesh - -class Property(unittest.TestCase): - - def setUp(self): - self.mesh = openmesh.TriMesh() - self.vhandle = [] - - def test_vertex_property_copy_properties_int(self): - # Add some vertices - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 0, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0))) - - # Add two faces - face_vhandles = [] - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[0]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[3]) - self.mesh.add_face(face_vhandles) - - # Test setup: - # 1 === 2 - # | / | - # | / | - # | / | - # 0 === 3 - - # Check setup - self.assertEqual(self.mesh.n_vertices(), 4) - self.assertEqual(self.mesh.n_faces(), 2) - - # Add a vertex property - intHandle = openmesh.VPropHandle() - self.assertFalse(self.mesh.get_property_handle(intHandle, "intProp")) - self.mesh.add_property(intHandle, "intProp") - self.assertTrue(self.mesh.get_property_handle(intHandle, "intProp")) - - # Fill property - for vh in self.mesh.vertices(): - self.mesh.set_property(intHandle, vh, vh.idx()) - - # Check if property it is ok - v_it = self.mesh.vertices() - self.assertEqual(self.mesh.property(intHandle, v_it.next()), 0) - self.assertEqual(self.mesh.property(intHandle, v_it.next()), 1) - self.assertEqual(self.mesh.property(intHandle, v_it.next()), 2) - self.assertEqual(self.mesh.property(intHandle, v_it.next()), 3) - - # Check vertex positions - v_it = self.mesh.vertices() - vh = v_it.next() - self.assertEqual(self.mesh.point(vh)[0], 0) - self.assertEqual(self.mesh.point(vh)[1], 0) - self.assertEqual(self.mesh.point(vh)[2], 0) - vh = v_it.next() - self.assertEqual(self.mesh.point(vh)[0], 0) - self.assertEqual(self.mesh.point(vh)[1], 1) - self.assertEqual(self.mesh.point(vh)[2], 0) - vh = v_it.next() - self.assertEqual(self.mesh.point(vh)[0], 1) - self.assertEqual(self.mesh.point(vh)[1], 1) - self.assertEqual(self.mesh.point(vh)[2], 0) - vh = v_it.next() - self.assertEqual(self.mesh.point(vh)[0], 1) - self.assertEqual(self.mesh.point(vh)[1], 0) - self.assertEqual(self.mesh.point(vh)[2], 0) - - # Copy from vertex 1 to 0, with skipping build in properties - self.mesh.copy_all_properties(self.vhandle[1], self.vhandle[0]) - v_it = self.mesh.vertices() - vh = v_it.next() - self.assertEqual(self.mesh.point(vh)[0], 0) - self.assertEqual(self.mesh.point(vh)[1], 0) - self.assertEqual(self.mesh.point(vh)[2], 0) - vh = v_it.next() - self.assertEqual(self.mesh.point(vh)[0], 0) - self.assertEqual(self.mesh.point(vh)[1], 1) - self.assertEqual(self.mesh.point(vh)[2], 0) - vh = v_it.next() - self.assertEqual(self.mesh.point(vh)[0], 1) - self.assertEqual(self.mesh.point(vh)[1], 1) - self.assertEqual(self.mesh.point(vh)[2], 0) - vh = v_it.next() - self.assertEqual(self.mesh.point(vh)[0], 1) - self.assertEqual(self.mesh.point(vh)[1], 0) - self.assertEqual(self.mesh.point(vh)[2], 0) - v_it = self.mesh.vertices() - self.assertEqual(self.mesh.property(intHandle, v_it.next()), 1) - self.assertEqual(self.mesh.property(intHandle, v_it.next()), 1) - self.assertEqual(self.mesh.property(intHandle, v_it.next()), 2) - self.assertEqual(self.mesh.property(intHandle, v_it.next()), 3) - - # Copy from vertex 2 to 3, including build in properties - self.mesh.copy_all_properties(self.vhandle[2], self.vhandle[3], True) - v_it = self.mesh.vertices() - vh = v_it.next() - self.assertEqual(self.mesh.point(vh)[0], 0) - self.assertEqual(self.mesh.point(vh)[1], 0) - self.assertEqual(self.mesh.point(vh)[2], 0) - vh = v_it.next() - self.assertEqual(self.mesh.point(vh)[0], 0) - self.assertEqual(self.mesh.point(vh)[1], 1) - self.assertEqual(self.mesh.point(vh)[2], 0) - vh = v_it.next() - self.assertEqual(self.mesh.point(vh)[0], 1) - self.assertEqual(self.mesh.point(vh)[1], 1) - self.assertEqual(self.mesh.point(vh)[2], 0) - vh = v_it.next() - self.assertEqual(self.mesh.point(vh)[0], 1) - self.assertEqual(self.mesh.point(vh)[1], 1) - self.assertEqual(self.mesh.point(vh)[2], 0) - v_it = self.mesh.vertices() - self.assertEqual(self.mesh.property(intHandle, v_it.next()), 1) - self.assertEqual(self.mesh.property(intHandle, v_it.next()), 1) - self.assertEqual(self.mesh.property(intHandle, v_it.next()), 2) - self.assertEqual(self.mesh.property(intHandle, v_it.next()), 2) - - def test_check_status_properties_halfedge_edge_all_deleted(self): - self.mesh.request_vertex_status() - self.mesh.request_face_status() - self.mesh.request_halfedge_status() - self.mesh.request_edge_status() - - # Define positions - p1 = openmesh.Vec3d(0, 0, 0) - p2 = openmesh.Vec3d(0, 1, 0) - p3 = openmesh.Vec3d(1, 1, 0) - p4 = openmesh.Vec3d(0, 0, 1) - - # Add some vertices - vh1 = self.mesh.add_vertex(p1) - vh2 = self.mesh.add_vertex(p2) - vh3 = self.mesh.add_vertex(p3) - vh4 = self.mesh.add_vertex(p4) - - # Add some faces - f1 = self.mesh.add_face(vh1, vh3, vh2) - f2 = self.mesh.add_face(vh1, vh2, vh4) - f3 = self.mesh.add_face(vh2, vh3, vh4) - f4 = self.mesh.add_face(vh3, vh1, vh4) - - # Delete all faces - self.mesh.delete_face(f1) - self.mesh.delete_face(f2) - self.mesh.delete_face(f3) - self.mesh.delete_face(f4) - - for heh in self.mesh.halfedges(): - self.assertTrue(self.mesh.status(self.mesh.edge_handle(heh)).deleted()) - self.assertTrue(self.mesh.status(heh).deleted()) - - def test_copy_all_properties_vertex_after_remove_of_property(self): - # Add some vertices - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 0, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0))) - - # Add two faces - face_vhandles = [] - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[0]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[3]) - self.mesh.add_face(face_vhandles) - - # Test setup: - # 1 === 2 - # | / | - # | / | - # | / | - # 0 === 3 - - # Check setup - self.assertEqual(self.mesh.n_vertices(), 4) - self.assertEqual(self.mesh.n_faces(), 2) - - # Add a double vertex property - doubleHandle = openmesh.VPropHandle() - self.assertFalse(self.mesh.get_property_handle(doubleHandle, "doubleProp")) - self.mesh.add_property(doubleHandle, "doubleProp") - self.assertTrue(self.mesh.get_property_handle(doubleHandle, "doubleProp")) - - # Add a int vertex property - intHandle = openmesh.VPropHandle() - self.assertFalse(self.mesh.get_property_handle(intHandle, "intProp")) - self.mesh.add_property(intHandle, "intProp") - self.assertTrue(self.mesh.get_property_handle(intHandle, "intProp")) - - # Now remove the double property again - self.mesh.remove_property(doubleHandle) - - # Fill int property - for vh in self.mesh.vertices(): - self.mesh.set_property(intHandle, vh, vh.idx()) - - # Check if property it is ok - v_it = self.mesh.vertices() - self.assertEqual(self.mesh.property(intHandle, v_it.next()), 0) - self.assertEqual(self.mesh.property(intHandle, v_it.next()), 1) - self.assertEqual(self.mesh.property(intHandle, v_it.next()), 2) - self.assertEqual(self.mesh.property(intHandle, v_it.next()), 3) - - # Check vertex positions - v_it = self.mesh.vertices() - vh = v_it.next() - self.assertEqual(self.mesh.point(vh)[0], 0) - self.assertEqual(self.mesh.point(vh)[1], 0) - self.assertEqual(self.mesh.point(vh)[2], 0) - vh = v_it.next() - self.assertEqual(self.mesh.point(vh)[0], 0) - self.assertEqual(self.mesh.point(vh)[1], 1) - self.assertEqual(self.mesh.point(vh)[2], 0) - vh = v_it.next() - self.assertEqual(self.mesh.point(vh)[0], 1) - self.assertEqual(self.mesh.point(vh)[1], 1) - self.assertEqual(self.mesh.point(vh)[2], 0) - vh = v_it.next() - self.assertEqual(self.mesh.point(vh)[0], 1) - self.assertEqual(self.mesh.point(vh)[1], 0) - self.assertEqual(self.mesh.point(vh)[2], 0) - - # Copy from vertex 1 to 0, with skipping build in properties - self.mesh.copy_all_properties(self.vhandle[1], self.vhandle[0]) - v_it = self.mesh.vertices() - vh = v_it.next() - self.assertEqual(self.mesh.point(vh)[0], 0) - self.assertEqual(self.mesh.point(vh)[1], 0) - self.assertEqual(self.mesh.point(vh)[2], 0) - vh = v_it.next() - self.assertEqual(self.mesh.point(vh)[0], 0) - self.assertEqual(self.mesh.point(vh)[1], 1) - self.assertEqual(self.mesh.point(vh)[2], 0) - vh = v_it.next() - self.assertEqual(self.mesh.point(vh)[0], 1) - self.assertEqual(self.mesh.point(vh)[1], 1) - self.assertEqual(self.mesh.point(vh)[2], 0) - vh = v_it.next() - self.assertEqual(self.mesh.point(vh)[0], 1) - self.assertEqual(self.mesh.point(vh)[1], 0) - self.assertEqual(self.mesh.point(vh)[2], 0) - v_it = self.mesh.vertices() - self.assertEqual(self.mesh.property(intHandle, v_it.next()), 1) - self.assertEqual(self.mesh.property(intHandle, v_it.next()), 1) - self.assertEqual(self.mesh.property(intHandle, v_it.next()), 2) - self.assertEqual(self.mesh.property(intHandle, v_it.next()), 3) - - # Copy from vertex 2 to 3, including build in properties - self.mesh.copy_all_properties(self.vhandle[2], self.vhandle[3], True) - v_it = self.mesh.vertices() - vh = v_it.next() - self.assertEqual(self.mesh.point(vh)[0], 0) - self.assertEqual(self.mesh.point(vh)[1], 0) - self.assertEqual(self.mesh.point(vh)[2], 0) - vh = v_it.next() - self.assertEqual(self.mesh.point(vh)[0], 0) - self.assertEqual(self.mesh.point(vh)[1], 1) - self.assertEqual(self.mesh.point(vh)[2], 0) - vh = v_it.next() - self.assertEqual(self.mesh.point(vh)[0], 1) - self.assertEqual(self.mesh.point(vh)[1], 1) - self.assertEqual(self.mesh.point(vh)[2], 0) - vh = v_it.next() - self.assertEqual(self.mesh.point(vh)[0], 1) - self.assertEqual(self.mesh.point(vh)[1], 1) - self.assertEqual(self.mesh.point(vh)[2], 0) - v_it = self.mesh.vertices() - self.assertEqual(self.mesh.property(intHandle, v_it.next()), 1) - self.assertEqual(self.mesh.property(intHandle, v_it.next()), 1) - self.assertEqual(self.mesh.property(intHandle, v_it.next()), 2) - self.assertEqual(self.mesh.property(intHandle, v_it.next()), 2) - -if __name__ == '__main__': - suite = unittest.TestLoader().loadTestsFromTestCase(Property) - unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/src/Python/Unittests/test_python.py b/src/Python/Unittests/test_python.py deleted file mode 100644 index f7d75492..00000000 --- a/src/Python/Unittests/test_python.py +++ /dev/null @@ -1,71 +0,0 @@ -import unittest -import openmesh - -class Python(unittest.TestCase): - - def setUp(self): - self.mesh = openmesh.TriMesh() - - # Add some vertices - self.vhandle = [] - - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0,-1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2,-1, 0))) - - # Add four faces using Python lists - vertex_list = [self.vhandle[0], self.vhandle[1], self.vhandle[2]] - self.mesh.add_face(vertex_list) - vertex_list = [self.vhandle[1], self.vhandle[3], self.vhandle[4]] - self.mesh.add_face(vertex_list) - vertex_list = [self.vhandle[0], self.vhandle[3], self.vhandle[1]] - self.mesh.add_face(vertex_list) - vertex_list = [self.vhandle[2], self.vhandle[1], self.vhandle[4]] - self.mesh.add_face(vertex_list) - - # Test setup: - # 0 ==== 2 - # |\ 0 /| - # | \ / | - # |2 1 3| - # | / \ | - # |/ 1 \| - # 3 ==== 4 - - def test_python_iterator(self): - # Iterate over all vertices - indices = [0, 1, 2, 3, 4] - for v, idx in zip(self.mesh.vertices(), indices): - self.assertEqual(v.idx(), idx) - - def test_python_circulator(self): - # Iterate around vertex 1 at the middle - indices = [4, 3, 0, 2] - for v, idx in zip(self.mesh.vv(self.vhandle[1]), indices): - self.assertEqual(v.idx(), idx) - - def test_property_manager(self): - # Check if vertex property exists - self.assertFalse(openmesh.VPropertyManager.property_exists(self.mesh, "prop")) - - # Create a new vertex property - propman = openmesh.VPropertyManager(self.mesh, "prop") - self.assertTrue(propman.property_exists(self.mesh, "prop")) - - # Check initial property values - for v in self.mesh.vertices(): - self.assertEqual(propman[v], None) - - # Set property values - propman.set_range(self.mesh.vertices(), 0.0) - - # Check again - for v in self.mesh.vertices(): - self.assertEqual(propman[v], 0.0) - - -if __name__ == '__main__': - suite = unittest.TestLoader().loadTestsFromTestCase(Python) - unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/src/Python/Unittests/test_read_write_obj.py b/src/Python/Unittests/test_read_write_obj.py deleted file mode 100644 index da2bfa41..00000000 --- a/src/Python/Unittests/test_read_write_obj.py +++ /dev/null @@ -1,229 +0,0 @@ -import unittest -import openmesh - -class ReadWriteOBJ(unittest.TestCase): - - def setUp(self): - self.mesh = openmesh.TriMesh() - - def test_load_simple_obj(self): - ok = openmesh.read_mesh(self.mesh, "cube-minimal.obj") - - self.assertTrue(ok) - - self.assertEqual(self.mesh.n_vertices(), 8) - self.assertEqual(self.mesh.n_edges(), 18) - self.assertEqual(self.mesh.n_faces(), 12) - - def test_load_simple_obj_check_halfedge_and_vertex_normals(self): - self.mesh.request_halfedge_normals() - self.mesh.request_vertex_normals() - - options = openmesh.Options() - options += openmesh.Options.VertexNormal - - file_name = "cube-minimal.obj" - - ok = openmesh.read_mesh(self.mesh, file_name, options) - - self.assertTrue(ok) - - self.assertEqual(self.mesh.n_vertices(), 8) - self.assertEqual(self.mesh.n_edges(), 18) - self.assertEqual(self.mesh.n_faces(), 12) - self.assertEqual(self.mesh.n_halfedges(), 36) - - # ===================================================== - # Check vertex normals - # ===================================================== - - self.assertEqual(self.mesh.normal(self.mesh.vertex_handle(0))[0], 0.0) - self.assertEqual(self.mesh.normal(self.mesh.vertex_handle(0))[1], -1.0) - self.assertEqual(self.mesh.normal(self.mesh.vertex_handle(0))[2], 0.0) - - self.assertEqual(self.mesh.normal(self.mesh.vertex_handle(3))[0], 0.0) - self.assertEqual(self.mesh.normal(self.mesh.vertex_handle(3))[1], 0.0) - self.assertEqual(self.mesh.normal(self.mesh.vertex_handle(3))[2], 1.0) - - self.assertEqual(self.mesh.normal(self.mesh.vertex_handle(4))[0], 0.0) - self.assertEqual(self.mesh.normal(self.mesh.vertex_handle(4))[1], -1.0) - self.assertEqual(self.mesh.normal(self.mesh.vertex_handle(4))[2], 0.0) - - self.assertEqual(self.mesh.normal(self.mesh.vertex_handle(7))[0], 0.0) - self.assertEqual(self.mesh.normal(self.mesh.vertex_handle(7))[1], 0.0) - self.assertEqual(self.mesh.normal(self.mesh.vertex_handle(7))[2], 1.0) - - # ===================================================== - # Check halfedge normals - # ===================================================== - - self.assertEqual(self.mesh.normal(self.mesh.halfedge_handle( 0))[0], 0.0) - self.assertEqual(self.mesh.normal(self.mesh.halfedge_handle( 0))[1], 0.0) - self.assertEqual(self.mesh.normal(self.mesh.halfedge_handle( 0))[2], -1.0) - - self.assertEqual(self.mesh.normal(self.mesh.halfedge_handle(10))[0], -1.0) - self.assertEqual(self.mesh.normal(self.mesh.halfedge_handle(10))[1], 0.0) - self.assertEqual(self.mesh.normal(self.mesh.halfedge_handle(10))[2], 0.0) - - self.assertEqual(self.mesh.normal(self.mesh.halfedge_handle(19))[0], 0.0) - self.assertEqual(self.mesh.normal(self.mesh.halfedge_handle(19))[1], 1.0) - self.assertEqual(self.mesh.normal(self.mesh.halfedge_handle(19))[2], 0.0) - - self.assertEqual(self.mesh.normal(self.mesh.halfedge_handle(24))[0], 1.0) - self.assertEqual(self.mesh.normal(self.mesh.halfedge_handle(24))[1], 0.0) - self.assertEqual(self.mesh.normal(self.mesh.halfedge_handle(24))[2], 0.0) - - self.assertEqual(self.mesh.normal(self.mesh.halfedge_handle(30))[0], 0.0) - self.assertEqual(self.mesh.normal(self.mesh.halfedge_handle(30))[1], -1.0) - self.assertEqual(self.mesh.normal(self.mesh.halfedge_handle(30))[2], 0.0) - - self.assertEqual(self.mesh.normal(self.mesh.halfedge_handle(35))[0], 0.0) - self.assertEqual(self.mesh.normal(self.mesh.halfedge_handle(35))[1], 0.0) - self.assertEqual(self.mesh.normal(self.mesh.halfedge_handle(35))[2], 1.0) - - self.mesh.release_vertex_normals() - self.mesh.release_halfedge_normals() - - def test_load_simple_obj_force_vertex_colors_although_not_available(self): - self.mesh.request_vertex_colors() - - file_name = "cube-minimal.obj" - - options = openmesh.Options() - options += openmesh.Options.VertexColor - - ok = openmesh.read_mesh(self.mesh, file_name, options) - - self.assertTrue(ok) - - self.assertEqual(self.mesh.n_vertices(), 8) - self.assertEqual(self.mesh.n_edges(), 18) - self.assertEqual(self.mesh.n_faces(), 12) - self.assertEqual(self.mesh.n_halfedges(), 36) - - def test_load_simple_obj_check_texcoords(self): - self.mesh.request_halfedge_texcoords2D() - - options = openmesh.Options() - options += openmesh.Options.FaceTexCoord - - file_name = "cube-minimal-texCoords.obj" - - ok = openmesh.read_mesh(self.mesh, file_name, options) - - self.assertTrue(ok) - - self.assertEqual(self.mesh.texcoord2D(self.mesh.halfedge_handle( 0))[0], 1.0) - self.assertEqual(self.mesh.texcoord2D(self.mesh.halfedge_handle( 0))[1], 1.0) - - self.assertEqual(self.mesh.texcoord2D(self.mesh.halfedge_handle(10))[0], 3.0) - self.assertEqual(self.mesh.texcoord2D(self.mesh.halfedge_handle(10))[1], 3.0) - - self.assertEqual(self.mesh.texcoord2D(self.mesh.halfedge_handle(19))[0], 6.0) - self.assertEqual(self.mesh.texcoord2D(self.mesh.halfedge_handle(19))[1], 6.0) - - self.assertEqual(self.mesh.texcoord2D(self.mesh.halfedge_handle(24))[0], 7.0) - self.assertEqual(self.mesh.texcoord2D(self.mesh.halfedge_handle(24))[1], 7.0) - - self.assertEqual(self.mesh.texcoord2D(self.mesh.halfedge_handle(30))[0], 9.0) - self.assertEqual(self.mesh.texcoord2D(self.mesh.halfedge_handle(30))[1], 9.0) - - self.assertEqual(self.mesh.texcoord2D(self.mesh.halfedge_handle(35))[0], 12.0) - self.assertEqual(self.mesh.texcoord2D(self.mesh.halfedge_handle(35))[1], 12.0) - - self.mesh.release_halfedge_texcoords2D() - - def test_load_obj_with_material(self): - self.mesh.request_face_colors() - - options = openmesh.Options() - options += openmesh.Options.FaceColor - - file_name = "square_material.obj" - - ok = openmesh.read_mesh(self.mesh, file_name, options) - - self.assertTrue(ok) - - fh = self.mesh.face_handle(self.mesh.halfedge_handle(0)) - - self.assertTrue(fh.is_valid()) - - self.assertAlmostEqual(self.mesh.color(fh)[0], 0.5, 2) - self.assertAlmostEqual(self.mesh.color(fh)[1], 0.5, 2) - self.assertAlmostEqual(self.mesh.color(fh)[2], 0.5, 2) - - self.mesh.release_face_colors() - - def test_load_simple_obj_with_vertex_colors_after_vertices(self): - self.mesh.request_vertex_colors() - - options = openmesh.Options() - options += openmesh.Options.VertexColor - - file_name = "cube-minimal-vertex-colors-after-vertex-definition.obj" - - ok = openmesh.read_mesh(self.mesh, file_name, options) - - self.assertTrue(ok) - - self.assertEqual(self.mesh.n_vertices(), 8) - self.assertEqual(self.mesh.n_edges(), 18) - self.assertEqual(self.mesh.n_faces(), 12) - - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[0], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[1], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[2], 0.0) - - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[0], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[1], 1.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[2], 1.0) - - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[0], 1.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[1], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[2], 0.0) - - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[0], 1.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[1], 1.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[2], 1.0) - - self.mesh.release_vertex_colors() - - def test_load_simple_obj_with_vertex_colors_as_vc_lines(self): - self.mesh.request_vertex_colors() - - options = openmesh.Options() - options += openmesh.Options.VertexColor - - file_name = "cube-minimal-vertex-colors-as-vc-lines.obj" - - ok = openmesh.read_mesh(self.mesh, file_name, options) - - self.assertTrue(ok) - - self.assertEqual(self.mesh.n_vertices(), 8) - self.assertEqual(self.mesh.n_edges(), 18) - self.assertEqual(self.mesh.n_faces(), 12) - - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[0], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[1], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[2], 0.0) - - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[0], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[1], 1.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[2], 1.0) - - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[0], 1.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[1], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[2], 0.0) - - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[0], 1.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[1], 1.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[2], 1.0) - - self.mesh.release_vertex_colors() - - -if __name__ == '__main__': - suite = unittest.TestLoader().loadTestsFromTestCase(ReadWriteOBJ) - unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/src/Python/Unittests/test_read_write_off.py b/src/Python/Unittests/test_read_write_off.py deleted file mode 100644 index a2d50b05..00000000 --- a/src/Python/Unittests/test_read_write_off.py +++ /dev/null @@ -1,163 +0,0 @@ -import unittest -import openmesh - -class ReadWriteOFF(unittest.TestCase): - - def setUp(self): - self.mesh = openmesh.TriMesh() - - def test_load_simple_off_file(self): - ok = openmesh.read_mesh(self.mesh, "cube1.off") - - self.assertTrue(ok) - - self.assertEqual(self.mesh.n_vertices(), 7526) - self.assertEqual(self.mesh.n_edges(), 22572) - self.assertEqual(self.mesh.n_faces(), 15048) - - def test_write_and_read_vertex_colors_to_and_from_off_file(self): - self.mesh.request_vertex_colors() - - self.mesh.add_vertex(openmesh.Vec3d(0, 0, 1)) - self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0)) - self.mesh.add_vertex(openmesh.Vec3d(0, 1, 1)) - self.mesh.add_vertex(openmesh.Vec3d(1, 0, 1)) - - # Using the default openmesh Python color type - testColor = openmesh.Vec4f(1.0, 0.5, 0.25, 1.0) - - # Setting colors (different from black) - for v in self.mesh.vertices(): - self.mesh.set_color(v, testColor) - - # Check if the colors are correctly set - count = 0 - for v in self.mesh.vertices(): - color = self.mesh.color(v) - if color[0] != testColor[0] or color[1] != testColor[1] or color[2] != testColor[2]: - count += 1 - - self.assertEqual(count, 0) - - options = openmesh.Options() - options += openmesh.Options.VertexColor - options += openmesh.Options.ColorFloat - - openmesh.write_mesh(self.mesh, "temp.off", options) - openmesh.read_mesh(self.mesh, "temp.off", options) - - # Check if vertices still have the same color - count = 0 - for v in self.mesh.vertices(): - color = self.mesh.color(v) - if color[0] != testColor[0] or color[1] != testColor[1] or color[2] != testColor[2]: - count += 1 - - self.assertEqual(count, 0) - - self.mesh.release_vertex_colors() - - def test_write_and_read_float_vertex_colors_to_and_from_off_file(self): - self.mesh.request_vertex_colors() - - options = openmesh.Options(openmesh.Options.VertexColor) - - ok = openmesh.read_mesh(self.mesh, "meshlab.ply", options) - - self.assertTrue(ok) - - options.clear() - options += openmesh.Options.VertexColor - options += openmesh.Options.ColorFloat - - # Write the mesh - ok = openmesh.write_mesh(self.mesh, "cube_floating.off", options) - self.assertTrue(ok) - ok = openmesh.read_mesh(self.mesh, "cube_floating.off", options) - self.assertTrue(ok) - - self.assertEqual(self.mesh.n_vertices(), 8) - self.assertEqual(self.mesh.n_edges(), 18) - self.assertEqual(self.mesh.n_faces(), 12) - - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[0], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[1], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[2], 1.0) - - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[0], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[1], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[2], 1.0) - - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[0], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[1], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[2], 1.0) - - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[0], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[1], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[2], 1.0) - - self.assertFalse(options.vertex_has_normal()) - self.assertFalse(options.vertex_has_texcoord()) - self.assertTrue(options.vertex_has_color()) - self.assertTrue(options.color_is_float()) - - self.mesh.release_vertex_colors() - - def test_write_and_read_binary_float_vertex_colors_to_and_from_off_file(self): - self.mesh.request_vertex_colors() - - options = openmesh.Options(openmesh.Options.VertexColor) - - ok = openmesh.read_mesh(self.mesh, "meshlab.ply", options) - - self.assertTrue(ok) - - options.clear() - options += openmesh.Options.VertexColor - options += openmesh.Options.Binary - options += openmesh.Options.ColorFloat - - # Write the mesh - ok = openmesh.write_mesh(self.mesh, "cube_floating_binary.off", options) - self.assertTrue(ok) - self.mesh.clear() - options.clear() - options += openmesh.Options.VertexColor - options += openmesh.Options.Binary - options += openmesh.Options.ColorFloat - ok = openmesh.read_mesh(self.mesh, "cube_floating_binary.off", options) - self.assertTrue(ok) - - self.assertEqual(self.mesh.n_vertices(), 8) - self.assertEqual(self.mesh.n_edges(), 18) - self.assertEqual(self.mesh.n_faces(), 12) - - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[0], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[1], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[2], 1.0) - - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[0], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[1], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[2], 1.0) - - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[0], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[1], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[2], 1.0) - - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[0], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[1], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[2], 1.0) - - self.assertFalse(options.vertex_has_normal()) - self.assertFalse(options.vertex_has_texcoord()) - self.assertFalse(options.face_has_color()) - self.assertTrue(options.vertex_has_color()) - self.assertTrue(options.color_is_float()) - self.assertTrue(options.is_binary()) - - self.mesh.release_vertex_colors() - - -if __name__ == '__main__': - suite = unittest.TestLoader().loadTestsFromTestCase(ReadWriteOFF) - unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/src/Python/Unittests/test_read_write_om.py b/src/Python/Unittests/test_read_write_om.py deleted file mode 100644 index dc8887ec..00000000 --- a/src/Python/Unittests/test_read_write_om.py +++ /dev/null @@ -1,201 +0,0 @@ -import unittest -import openmesh -import os - -class ReadWriteOM(unittest.TestCase): - - def setUp(self): - self.mesh = openmesh.TriMesh() - - def test_load_simple_om_force_vertex_colors_although_not_available(self): - self.mesh.request_vertex_colors() - - file_name = "cube-minimal.om" - - options = openmesh.Options() - options += openmesh.Options.VertexColor - - ok = openmesh.read_mesh(self.mesh, file_name, options) - - self.assertTrue(ok) - - self.assertEqual(self.mesh.n_vertices(), 8) - self.assertEqual(self.mesh.n_edges(), 18) - self.assertEqual(self.mesh.n_faces(), 12) - self.assertEqual(self.mesh.n_halfedges(), 36) - - self.assertFalse(options.vertex_has_normal()) - self.assertFalse(options.vertex_has_texcoord()) - self.assertFalse(options.vertex_has_color()) - - def test_load_simple_om_with_texcoords(self): - self.mesh.request_vertex_texcoords2D() - - options = openmesh.Options() - options += openmesh.Options.VertexTexCoord - - ok = openmesh.read_mesh(self.mesh, "cube-minimal-texCoords.om", options) - - self.assertTrue(ok) - - self.assertEqual(self.mesh.n_vertices(), 8) - self.assertEqual(self.mesh.n_edges(), 18) - self.assertEqual(self.mesh.n_faces(), 12) - - self.assertEqual(self.mesh.texcoord2D(self.mesh.vertex_handle(0))[0], 10.0) - self.assertEqual(self.mesh.texcoord2D(self.mesh.vertex_handle(0))[1], 10.0) - - self.assertEqual(self.mesh.texcoord2D(self.mesh.vertex_handle(2))[0], 6.0) - self.assertEqual(self.mesh.texcoord2D(self.mesh.vertex_handle(2))[1], 6.0) - - self.assertEqual(self.mesh.texcoord2D(self.mesh.vertex_handle(4))[0], 9.0) - self.assertEqual(self.mesh.texcoord2D(self.mesh.vertex_handle(4))[1], 9.0) - - self.assertEqual(self.mesh.texcoord2D(self.mesh.vertex_handle(7))[0], 12.0) - self.assertEqual(self.mesh.texcoord2D(self.mesh.vertex_handle(7))[1], 12.0) - - self.assertFalse(options.vertex_has_normal()) - self.assertTrue(options.vertex_has_texcoord()) - self.assertFalse(options.vertex_has_color()) - - self.mesh.release_vertex_texcoords2D() - - def test_load_simple_om_with_vertex_colors(self): - self.mesh.request_vertex_colors() - - options = openmesh.Options() - options += openmesh.Options.VertexColor - - ok = openmesh.read_mesh(self.mesh, "cube-minimal-vertexColors.om", options) - - self.assertTrue(ok) - - self.assertEqual(self.mesh.n_vertices(), 8) - self.assertEqual(self.mesh.n_edges(), 18) - self.assertEqual(self.mesh.n_faces(), 12) - - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[0], 1.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[1], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[2], 0.0) - - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[0], 1.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[1], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[2], 0.0) - - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[0], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[1], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[2], 1.0) - - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[0], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[1], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[2], 1.0) - - self.assertFalse(options.vertex_has_normal()) - self.assertFalse(options.vertex_has_texcoord()) - self.assertTrue(options.vertex_has_color()) - - self.mesh.release_vertex_colors() - - def test_write_triangle(self): - filename = "triangle-minimal.om"; - - # Generate data - v1 = self.mesh.add_vertex(openmesh.Vec3d(1.0, 0.0, 0.0)) - v2 = self.mesh.add_vertex(openmesh.Vec3d(0.0, 1.0, 0.0)) - v3 = self.mesh.add_vertex(openmesh.Vec3d(0.0, 0.0, 1.0)) - self.mesh.add_face(v1, v2, v3) - - # Save - ok = openmesh.write_mesh(self.mesh, filename) - self.assertTrue(ok) - - # Reset - self.mesh.clear() - - # Load - ok = openmesh.read_mesh(self.mesh, filename) - self.assertTrue(ok) - - # Compare - self.assertEqual(self.mesh.n_vertices(), 3) - self.assertEqual(self.mesh.n_edges(), 3) - self.assertEqual(self.mesh.n_faces(), 1) - - self.assertEqual(self.mesh.point(v1), openmesh.Vec3d(1.0, 0.0, 0.0)) - self.assertEqual(self.mesh.point(v2), openmesh.Vec3d(0.0, 1.0, 0.0)) - self.assertEqual(self.mesh.point(v3), openmesh.Vec3d(0.0, 0.0, 1.0)) - - # Cleanup - os.remove(filename) - - def test_write_triangle_vertex_integer_color(self): - self.mesh.request_vertex_colors() - - options = openmesh.Options() - options += openmesh.Options.VertexColor - options += openmesh.Options.ColorFloat - - filename = "triangle-minimal-ColorsPerVertex.om" - - # Generate data - v1 = self.mesh.add_vertex(openmesh.Vec3d(1.0, 0.0, 0.0)) - v2 = self.mesh.add_vertex(openmesh.Vec3d(0.0, 1.0, 0.0)) - v3 = self.mesh.add_vertex(openmesh.Vec3d(0.0, 0.0, 1.0)) - self.mesh.add_face(v1, v2, v3) - - c1 = openmesh.Vec4f(0.00, 0.00, 0.50, 1.00) - c2 = openmesh.Vec4f(0.25, 0.00, 0.00, 1.00) - c3 = openmesh.Vec4f(0.00, 0.75, 0.00, 1.00) - - self.mesh.set_color(v1, c1) - self.mesh.set_color(v2, c2) - self.mesh.set_color(v3, c3) - - # Save - ok = openmesh.write_mesh(self.mesh, filename, options) - self.assertTrue(ok) - - self.mesh.release_vertex_colors() - - # Load - cmpMesh = openmesh.TriMesh() - cmpMesh.request_vertex_colors() - ok = openmesh.read_mesh(cmpMesh, filename, options) - self.assertTrue(ok) - - self.assertTrue(cmpMesh.has_vertex_colors()) - - # Compare - self.assertEqual(self.mesh.n_vertices(), 3) - self.assertEqual(self.mesh.n_edges(), 3) - self.assertEqual(self.mesh.n_faces(), 1) - - self.assertEqual(cmpMesh.point(v1), openmesh.Vec3d(1.0, 0.0, 0.0)) - self.assertEqual(cmpMesh.point(v2), openmesh.Vec3d(0.0, 1.0, 0.0)) - self.assertEqual(cmpMesh.point(v3), openmesh.Vec3d(0.0, 0.0, 1.0)) - - self.assertAlmostEqual(cmpMesh.color(v1)[0], c1[0], 2) - self.assertAlmostEqual(cmpMesh.color(v1)[1], c1[1], 2) - self.assertAlmostEqual(cmpMesh.color(v1)[2], c1[2], 2) - self.assertAlmostEqual(cmpMesh.color(v1)[3], c1[3], 2) - - self.assertAlmostEqual(cmpMesh.color(v2)[0], c2[0], 2) - self.assertAlmostEqual(cmpMesh.color(v2)[1], c2[1], 2) - self.assertAlmostEqual(cmpMesh.color(v2)[2], c2[2], 2) - self.assertAlmostEqual(cmpMesh.color(v2)[3], c2[3], 2) - - self.assertAlmostEqual(cmpMesh.color(v3)[0], c3[0], 2) - self.assertAlmostEqual(cmpMesh.color(v3)[1], c3[1], 2) - self.assertAlmostEqual(cmpMesh.color(v3)[2], c3[2], 2) - self.assertAlmostEqual(cmpMesh.color(v3)[3], c3[3], 2) - - # Clean up - cmpMesh.release_vertex_colors() - os.remove(filename) - - # TODO property tests - - -if __name__ == '__main__': - suite = unittest.TestLoader().loadTestsFromTestCase(ReadWriteOM) - unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/src/Python/Unittests/test_read_write_ply.py b/src/Python/Unittests/test_read_write_ply.py deleted file mode 100644 index 7de00b1e..00000000 --- a/src/Python/Unittests/test_read_write_ply.py +++ /dev/null @@ -1,342 +0,0 @@ -import unittest -import openmesh - -class ReadWritePLY(unittest.TestCase): - - def setUp(self): - self.mesh = openmesh.TriMesh() - - def test_load_simple_point_ply_file_with_bad_encoding(self): - ok = openmesh.read_mesh(self.mesh, "pointCloudBadEncoding.ply") - - self.assertTrue(ok) - - self.assertEqual(self.mesh.n_vertices(), 10) - self.assertEqual(self.mesh.n_edges(), 0) - self.assertEqual(self.mesh.n_faces(), 0) - - def test_load_simple_point_ply_file_with_good_encoding(self): - ok = openmesh.read_mesh(self.mesh, "pointCloudGoodEncoding.ply") - - self.assertTrue(ok) - - self.assertEqual(self.mesh.n_vertices(), 10) - self.assertEqual(self.mesh.n_edges(), 0) - self.assertEqual(self.mesh.n_faces(), 0) - - def test_load_simple_ply(self): - ok = openmesh.read_mesh(self.mesh, "cube-minimal.ply") - - self.assertTrue(ok) - - self.assertEqual(self.mesh.n_vertices(), 8) - self.assertEqual(self.mesh.n_edges(), 18) - self.assertEqual(self.mesh.n_faces(), 12) - - def test_load_simple_ply_force_vertex_colors_although_not_available(self): - self.mesh.request_vertex_colors() - - file_name = "cube-minimal.ply" - - options = openmesh.Options() - options += openmesh.Options.VertexColor - - ok = openmesh.read_mesh(self.mesh, file_name, options) - - self.assertTrue(ok) - - self.assertEqual(self.mesh.n_vertices(), 8) - self.assertEqual(self.mesh.n_edges(), 18) - self.assertEqual(self.mesh.n_faces(), 12) - self.assertEqual(self.mesh.n_halfedges(), 36) - - self.assertFalse(options.vertex_has_normal()) - self.assertFalse(options.vertex_has_texcoord()) - self.assertFalse(options.vertex_has_color()) - - def test_load_simple_ply_with_vertex_colors(self): - self.mesh.request_vertex_colors() - - file_name = "cube-minimal.ply" - - options = openmesh.Options() - options += openmesh.Options.VertexColor - - ok = openmesh.read_mesh(self.mesh, "cube-minimal-vertexColors.ply", options) - - self.assertTrue(ok) - - self.assertEqual(self.mesh.n_vertices(), 8) - self.assertEqual(self.mesh.n_edges(), 18) - self.assertEqual(self.mesh.n_faces(), 12) - - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[0], 1.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[1], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[2], 0.0) - - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[0], 1.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[1], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[2], 0.0) - - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[0], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[1], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[2], 1.0) - - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[0], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[1], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[2], 1.0) - - self.assertFalse(options.vertex_has_normal()) - self.assertFalse(options.vertex_has_texcoord()) - self.assertTrue(options.vertex_has_color()) - - self.mesh.release_vertex_colors() - - def test_load_ply_from_mesh_lab_with_vertex_colors(self): - self.mesh.request_vertex_colors() - - options = openmesh.Options() - options += openmesh.Options.VertexColor - - ok = openmesh.read_mesh(self.mesh, "meshlab.ply", options) - - self.assertTrue(ok) - - self.assertEqual(self.mesh.n_vertices(), 8) - self.assertEqual(self.mesh.n_edges(), 18) - self.assertEqual(self.mesh.n_faces(), 12) - - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[0], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[1], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[2], 1.0) - - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[0], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[1], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[2], 1.0) - - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[0], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[1], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[2], 1.0) - - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[0], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[1], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[2], 1.0) - - self.assertFalse(options.vertex_has_normal()) - self.assertFalse(options.vertex_has_texcoord()) - self.assertTrue(options.vertex_has_color()) - - self.mesh.release_vertex_colors() - - def test_write_and_read_binary_ply_with_vertex_colors(self): - self.mesh.request_vertex_colors() - - options = openmesh.Options() - options += openmesh.Options.VertexColor - - ok = openmesh.read_mesh(self.mesh, "meshlab.ply", options) - - self.assertTrue(ok) - - options += openmesh.Options.Binary - - ok = openmesh.write_mesh(self.mesh, "meshlab_binary.ply", options) - self.assertTrue(ok) - - self.mesh.clear - - ok = openmesh.read_mesh(self.mesh, "meshlab_binary.ply", options) - self.assertTrue(ok) - - self.assertEqual(self.mesh.n_vertices(), 8) - self.assertEqual(self.mesh.n_edges(), 18) - self.assertEqual(self.mesh.n_faces(), 12) - - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[0], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[1], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[2], 1.0) - - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[0], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[1], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[2], 1.0) - - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[0], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[1], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[2], 1.0) - - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[0], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[1], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[2], 1.0) - - self.assertFalse(options.vertex_has_normal()) - self.assertFalse(options.vertex_has_texcoord()) - self.assertTrue(options.vertex_has_color()) - - self.mesh.release_vertex_colors() - - def test_write_and_read_ply_with_float_vertex_colors(self): - self.mesh.request_vertex_colors() - - options = openmesh.Options() - options += openmesh.Options.VertexColor - - ok = openmesh.read_mesh(self.mesh, "meshlab.ply", options) - - self.assertTrue(ok) - - options += openmesh.Options.ColorFloat - - ok = openmesh.write_mesh(self.mesh, "meshlab_float.ply", options) - self.assertTrue(ok) - - self.mesh.clear - ok = openmesh.read_mesh(self.mesh, "meshlab_float.ply", options) - self.assertTrue(ok) - - self.assertEqual(self.mesh.n_vertices(), 8) - self.assertEqual(self.mesh.n_edges(), 18) - self.assertEqual(self.mesh.n_faces(), 12) - - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[0], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[1], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[2], 1.0) - - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[0], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[1], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[2], 1.0) - - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[0], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[1], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[2], 1.0) - - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[0], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[1], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[2], 1.0) - - self.assertFalse(options.vertex_has_normal()) - self.assertFalse(options.vertex_has_texcoord()) - self.assertTrue(options.vertex_has_color()) - self.assertTrue(options.color_is_float()) - - self.mesh.release_vertex_colors() - - def test_write_and_read_binary_ply_with_float_vertex_colors(self): - self.mesh.request_vertex_colors() - - options = openmesh.Options() - options += openmesh.Options.VertexColor - - ok = openmesh.read_mesh(self.mesh, "meshlab.ply", options) - - self.assertTrue(ok) - - options += openmesh.Options.ColorFloat - options += openmesh.Options.Binary - - ok = openmesh.write_mesh(self.mesh, "meshlab_binary_float.ply", options) - self.assertTrue(ok) - - self.mesh.clear - ok = openmesh.read_mesh(self.mesh, "meshlab_binary_float.ply", options) - self.assertTrue(ok) - - self.assertEqual(self.mesh.n_vertices(), 8) - self.assertEqual(self.mesh.n_edges(), 18) - self.assertEqual(self.mesh.n_faces(), 12) - - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[0], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[1], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[2], 1.0) - - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[0], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[1], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[2], 1.0) - - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[0], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[1], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[2], 1.0) - - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[0], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[1], 0.0) - self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[2], 1.0) - - self.assertFalse(options.vertex_has_normal()) - self.assertFalse(options.vertex_has_texcoord()) - self.assertTrue(options.vertex_has_color()) - self.assertTrue(options.color_is_float()) - self.assertTrue(options.is_binary()) - - self.mesh.release_vertex_colors() - - def test_load_simple_ply_with_texcoords(self): - self.mesh.request_vertex_texcoords2D() - - options = openmesh.Options() - options += openmesh.Options.VertexTexCoord - - ok = openmesh.read_mesh(self.mesh, "cube-minimal-texCoords.ply", options) - - self.assertTrue(ok) - - self.assertEqual(self.mesh.n_vertices(), 8) - self.assertEqual(self.mesh.n_edges(), 18) - self.assertEqual(self.mesh.n_faces(), 12) - - self.assertEqual(self.mesh.texcoord2D(self.mesh.vertex_handle(0))[0], 10.0) - self.assertEqual(self.mesh.texcoord2D(self.mesh.vertex_handle(0))[1], 10.0) - - self.assertEqual(self.mesh.texcoord2D(self.mesh.vertex_handle(2))[0], 6.0) - self.assertEqual(self.mesh.texcoord2D(self.mesh.vertex_handle(2))[1], 6.0) - - self.assertEqual(self.mesh.texcoord2D(self.mesh.vertex_handle(4))[0], 9.0) - self.assertEqual(self.mesh.texcoord2D(self.mesh.vertex_handle(4))[1], 9.0) - - self.assertEqual(self.mesh.texcoord2D(self.mesh.vertex_handle(7))[0], 12.0) - self.assertEqual(self.mesh.texcoord2D(self.mesh.vertex_handle(7))[1], 12.0) - - self.assertFalse(options.vertex_has_normal()) - self.assertTrue(options.vertex_has_texcoord()) - self.assertFalse(options.vertex_has_color()) - - self.mesh.release_vertex_texcoords2D() - - def test_load_simple_ply_with_normals(self): - self.mesh.request_vertex_normals() - - options = openmesh.Options() - options += openmesh.Options.VertexNormal - - ok = openmesh.read_mesh(self.mesh, "cube-minimal-normals.ply", options) - - self.assertTrue(ok) - - self.assertEqual(self.mesh.n_vertices(), 8) - self.assertEqual(self.mesh.n_edges(), 18) - self.assertEqual(self.mesh.n_faces(), 12) - - self.assertTrue(options.vertex_has_normal()) - self.assertFalse(options.vertex_has_texcoord()) - self.assertFalse(options.vertex_has_color()) - - self.assertEqual(self.mesh.normal(self.mesh.vertex_handle(0))[0], 0.0) - self.assertEqual(self.mesh.normal(self.mesh.vertex_handle(0))[1], 0.0) - self.assertEqual(self.mesh.normal(self.mesh.vertex_handle(0))[2], 1.0) - - self.assertEqual(self.mesh.normal(self.mesh.vertex_handle(3))[0], 1.0) - self.assertEqual(self.mesh.normal(self.mesh.vertex_handle(3))[1], 0.0) - self.assertEqual(self.mesh.normal(self.mesh.vertex_handle(3))[2], 0.0) - - self.assertEqual(self.mesh.normal(self.mesh.vertex_handle(4))[0], 1.0) - self.assertEqual(self.mesh.normal(self.mesh.vertex_handle(4))[1], 0.0) - self.assertEqual(self.mesh.normal(self.mesh.vertex_handle(4))[2], 1.0) - - self.assertEqual(self.mesh.normal(self.mesh.vertex_handle(7))[0], 1.0) - self.assertEqual(self.mesh.normal(self.mesh.vertex_handle(7))[1], 1.0) - self.assertEqual(self.mesh.normal(self.mesh.vertex_handle(7))[2], 2.0) - - self.mesh.release_vertex_normals() - - -if __name__ == '__main__': - suite = unittest.TestLoader().loadTestsFromTestCase(ReadWritePLY) - unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/src/Python/Unittests/test_read_write_stl.py b/src/Python/Unittests/test_read_write_stl.py deleted file mode 100644 index b2ede2e0..00000000 --- a/src/Python/Unittests/test_read_write_stl.py +++ /dev/null @@ -1,75 +0,0 @@ -import unittest -import openmesh - -class ReadWriteSTL(unittest.TestCase): - - def setUp(self): - self.mesh = openmesh.TriMesh() - - def test_load_simple_stl_file(self): - ok = openmesh.read_mesh(self.mesh, "cube1.stl") - - self.assertTrue(ok) - - self.assertEqual(self.mesh.n_vertices(), 7526) - self.assertEqual(self.mesh.n_edges(), 22572) - self.assertEqual(self.mesh.n_faces(), 15048) - - def test_load_simple_stl_file_with_normals(self): - self.mesh.request_face_normals() - - options = openmesh.Options() - options += openmesh.Options.FaceNormal - - ok = openmesh.read_mesh(self.mesh, "cube1.stl", options) - - self.assertTrue(ok) - - self.assertAlmostEqual(self.mesh.normal(self.mesh.face_handle(0))[0], -0.038545) - self.assertAlmostEqual(self.mesh.normal(self.mesh.face_handle(0))[1], -0.004330) - self.assertAlmostEqual(self.mesh.normal(self.mesh.face_handle(0))[2], 0.999247) - - self.assertEqual(self.mesh.n_vertices(), 7526) - self.assertEqual(self.mesh.n_edges(), 22572) - self.assertEqual(self.mesh.n_faces(), 15048) - - self.mesh.release_face_normals() - - def test_load_simple_stl_binary_file(self): - ok = openmesh.read_mesh(self.mesh, "cube1Binary.stl") - - self.assertTrue(ok) - - self.assertEqual(self.mesh.n_vertices(), 7526) - self.assertEqual(self.mesh.n_edges(), 22572) - self.assertEqual(self.mesh.n_faces(), 15048) - - def test_load_simple_stl_binary_file_with_normals(self): - self.mesh.request_face_normals() - - options = openmesh.Options() - options += openmesh.Options.FaceNormal - options += openmesh.Options.Binary - - ok = openmesh.read_mesh(self.mesh, "cube1Binary.stl", options) - - self.assertTrue(ok) - - self.assertTrue(options.is_binary()) - self.assertTrue(options.face_has_normal()) - self.assertFalse(options.vertex_has_normal()) - - self.assertAlmostEqual(self.mesh.normal(self.mesh.face_handle(0))[0], -0.038545, 5) - self.assertAlmostEqual(self.mesh.normal(self.mesh.face_handle(0))[1], -0.004330, 5) - self.assertAlmostEqual(self.mesh.normal(self.mesh.face_handle(0))[2], 0.999247, 5) - - self.assertEqual(self.mesh.n_vertices(), 7526) - self.assertEqual(self.mesh.n_edges(), 22572) - self.assertEqual(self.mesh.n_faces(), 15048) - - self.mesh.release_face_normals() - - -if __name__ == '__main__': - suite = unittest.TestLoader().loadTestsFromTestCase(ReadWriteSTL) - unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/src/Python/Unittests/test_split_copy.py b/src/Python/Unittests/test_split_copy.py deleted file mode 100644 index 0252f593..00000000 --- a/src/Python/Unittests/test_split_copy.py +++ /dev/null @@ -1,87 +0,0 @@ -import unittest -import openmesh - -class SplitCopy(unittest.TestCase): - - def test_split_copy_triangle_mesh(self): - self.mesh = openmesh.TriMesh() - self.vhandle = [] - - # Add some vertices - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 0, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0.25, 0.25, 0))) - - # Add one face - face_vhandles = [] - - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[0]) - - fh = self.mesh.add_face(face_vhandles) - - # Test setup: - # 1 === 2 - # | / - # | / - # | / - # 0 - - # Set property - fprop_int = openmesh.FPropHandle() - self.mesh.add_property(fprop_int) - self.mesh.set_property(fprop_int, fh, 999) - - # Split face with new vertex - self.mesh.split_copy(fh, self.vhandle[3]) - - # Check setup - for f in self.mesh.faces(): - self.assertEqual(self.mesh.property(fprop_int, f), 999) - - def test_split_copy_polymesh(self): - self.mesh = openmesh.PolyMesh() - self.vhandle = [] - - # Add some vertices - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 0, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0.5, 0.5, 0))) - - # Add one face - face_vhandles = [] - - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[3]) - - fh = self.mesh.add_face(face_vhandles) - - # Test setup: - # 1 === 2 - # | | - # | | - # | | - # 0 === 3 - - # Set property - fprop_int = openmesh.FPropHandle() - self.mesh.add_property(fprop_int) - self.mesh.set_property(fprop_int, fh, 999) - - # Split face with new vertex - self.mesh.split_copy(fh, self.vhandle[4]) - - # Check setup - for f in self.mesh.faces(): - self.assertEqual(self.mesh.property(fprop_int, f), 999) - - -if __name__ == '__main__': - suite = unittest.TestLoader().loadTestsFromTestCase(SplitCopy) - unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/src/Python/Unittests/test_trimesh_circulator_current_halfedge_handle_replacement.py b/src/Python/Unittests/test_trimesh_circulator_current_halfedge_handle_replacement.py deleted file mode 100644 index 8232c0ce..00000000 --- a/src/Python/Unittests/test_trimesh_circulator_current_halfedge_handle_replacement.py +++ /dev/null @@ -1,269 +0,0 @@ -import unittest -import openmesh - -class TrimeshCirculatorCurrentHalfedgeHandleReplacement(unittest.TestCase): - - def setUp(self): - self.mesh = openmesh.TriMesh() - self.vhandle = [] - - def test_dereference(self): - # Add some vertices - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, -1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, -1, 0))) - - # Add four faces - face_vhandles = [] - - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[2]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[3]) - face_vhandles.append(self.vhandle[4]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[3]) - face_vhandles.append(self.vhandle[1]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[4]) - self.mesh.add_face(face_vhandles) - - # Test setup: - # 0 ==== 2 - # |\ 0 /| - # | \ / | - # |2 1 3| - # | / \ | - # |/ 1 \| - # 3 ==== 4 - # Starting vertex is 1->4 - - # output from fh_it.current_halfedge_handle() - current_halfedge_handles = [4, 0, 2, 10, 6, 8, 1, 12, 7, 14, 3, 11] - - i = 0 - for f in self.mesh.faces(): - for he in self.mesh.fh(f): - self.assertEqual(he.idx(), current_halfedge_handles[i]) - i += 1 - - def test_vv_iter(self): - # Add some vertices - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, -1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, -1, 0))) - - # Add four faces - face_vhandles = [] - - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[2]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[3]) - face_vhandles.append(self.vhandle[4]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[3]) - face_vhandles.append(self.vhandle[1]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[4]) - self.mesh.add_face(face_vhandles) - - # Test setup: - # 0 ==== 2 - # |\ 0 /| - # | \ / | - # |2 1 3| - # | / \ | - # |/ 1 \| - # 3 ==== 4 - # Starting vertex is 1->4 - - # output from vv_it.current_halfedge_handle() - current_halfedge_handles = [5, 0, 12, 11, 6, 1, 2, 15, 3, 4, 13, 7, 8, 9, 10, 14] - - eh0 = [] - eh1 = [] - - i = 0 - - for v in self.mesh.vertices(): - for vv in self.mesh.vv(v): - he = openmesh.HalfedgeHandle(current_halfedge_handles[i]) - eh0.append(self.mesh.edge_handle(he)) - i += 1 - for v in self.mesh.vertices(): - for he in self.mesh.voh(v): - eh1.append(self.mesh.edge_handle(he)) - - self.assertEqual(len(eh0), len(eh1)) - for i in range(len(eh0)): - self.assertEqual(eh0[i], eh1[i]) - - def test_fe_iter(self): - # Add some vertices - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, -1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, -1, 0))) - - # Add four faces - face_vhandles = [] - - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[2]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[3]) - face_vhandles.append(self.vhandle[4]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[3]) - face_vhandles.append(self.vhandle[1]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[4]) - self.mesh.add_face(face_vhandles) - - # Test setup: - # 0 ==== 2 - # |\ 0 /| - # | \ / | - # |2 1 3| - # | / \ | - # |/ 1 \| - # 3 ==== 4 - # Starting vertex is 1->4 - - # output from fe_it.current_halfedge_handle() - current_halfedge_handles = [4, 0, 2, 10, 6, 8, 1, 12, 7, 14, 3, 11] - - heh0 = [] - heh1 = [] - - i = 0 - - for f in self.mesh.faces(): - for e in self.mesh.fe(f): - heh0.append(openmesh.HalfedgeHandle(current_halfedge_handles[i])) - i += 1 - for f in self.mesh.faces(): - for he in self.mesh.fh(f): - heh1.append(he) - - self.assertEqual(len(heh0), len(heh1)) - for i in range(len(heh0)): - self.assertEqual(heh0[i], heh1[i]) - - def test_vf_iter_boundary(self): - # Add some vertices - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(3, 0, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(4, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, -1, 0))) - - # Add three faces - face_vhandles = [] - - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[2]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[3]) - face_vhandles.append(self.vhandle[4]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[5]) - face_vhandles.append(self.vhandle[3]) - self.mesh.add_face(face_vhandles) - - # Test setup: - # - # 0 ------ 2 ------ 4 - # \ / \ / - # \ 0 / \ 1 / - # \ / \ / - # 1 ------- 3 - # \ / - # \ 2 / - # \ / - # \ / - # 5 - - # output from fe_it.current_halfedge_handle() - current_halfedge_handles = [0, 2, 12, 4, 6, 8, 16, 10, 14] - - fh0 = [] - fh1 = [] - - i = 0 - - for v in self.mesh.vertices(): - for f in self.mesh.vf(v): - he = openmesh.HalfedgeHandle(current_halfedge_handles[i]) - fh0.append(self.mesh.face_handle(he)) - i += 1 - for v in self.mesh.vertices(): - for f in self.mesh.vf(v): - fh1.append(f) - - self.assertEqual(len(fh0), len(fh1)) - for i in range(len(fh0)): - self.assertEqual(fh0[i], fh1[i]) - - -if __name__ == '__main__': - suite = unittest.TestLoader().loadTestsFromTestCase(TrimeshCirculatorCurrentHalfedgeHandleReplacement) - unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/src/Python/Unittests/test_trimesh_circulator_face_edge.py b/src/Python/Unittests/test_trimesh_circulator_face_edge.py deleted file mode 100644 index 91df16a7..00000000 --- a/src/Python/Unittests/test_trimesh_circulator_face_edge.py +++ /dev/null @@ -1,50 +0,0 @@ -import unittest -import openmesh - -class TriMeshCirculatorFaceEdge(unittest.TestCase): - - def setUp(self): - self.mesh = openmesh.TriMesh() - - # Add some vertices - self.vhandle = [] - - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(3, 0, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(4, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2,-1, 0))) - - # Add four faces - self.mesh.add_face(self.vhandle[0], self.vhandle[1], self.vhandle[2]) - self.mesh.add_face(self.vhandle[2], self.vhandle[1], self.vhandle[3]) - self.mesh.add_face(self.vhandle[2], self.vhandle[3], self.vhandle[4]) - self.mesh.add_face(self.vhandle[1], self.vhandle[5], self.vhandle[3]) - - ''' - Test setup: - 0 ------ 2 ------ 4 - \ / \ / - \ 0 / \ 2 / - \ / 1 \ / - 1 ------- 3 - \ / - \ 3 / - \ / - \ / - 5 - ''' - - def test_face_edge_iter_without_holes_increment(self): - # Iterate around face 1 at the middle - fe_it = openmesh.FaceEdgeIter(self.mesh, self.mesh.face_handle(1)) - self.assertEqual(fe_it.__next__().idx(), 4) - self.assertEqual(fe_it.__next__().idx(), 1) - self.assertEqual(fe_it.__next__().idx(), 3) - self.assertRaises(StopIteration, fe_it.__next__) - - -if __name__ == '__main__': - suite = unittest.TestLoader().loadTestsFromTestCase(TriMeshCirculatorFaceEdge) - unittest.TextTestRunner(verbosity=2).run(suite) \ No newline at end of file diff --git a/src/Python/Unittests/test_trimesh_circulator_face_face.py b/src/Python/Unittests/test_trimesh_circulator_face_face.py deleted file mode 100644 index 293c39c2..00000000 --- a/src/Python/Unittests/test_trimesh_circulator_face_face.py +++ /dev/null @@ -1,156 +0,0 @@ -import unittest -import openmesh - -class TrimeshCirculatorFaceFace(unittest.TestCase): - - def setUp(self): - self.mesh = openmesh.TriMesh() - self.vhandle = [] - - def test_face_face_iter_with_holes(self): - # Add some vertices - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(3, 0, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(4, 1, 0))) - - # Add three faces - face_vhandles = [] - - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[2]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[3]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[3]) - face_vhandles.append(self.vhandle[4]) - self.mesh.add_face(face_vhandles) - - # Test setup: - # - # 0 ------ 2 ------ 4 - # \ / \ / - # \ 0 / \ 2 / - # \ / 1 \ / - # 1 ------- 3 - - ff_it = self.mesh.ff(self.mesh.face_handle(1)) - - self.assertEqual(ff_it.__next__().idx(), 2) - self.assertEqual(ff_it.__next__().idx(), 0) - self.assertRaises(StopIteration, ff_it.__next__) - - def test_face_face_iter_without_holes(self): - # Add some vertices - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(3, 0, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(4, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, -1, 0))) - - # Add four faces - face_vhandles = [] - - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[2]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[3]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[3]) - face_vhandles.append(self.vhandle[4]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[5]) - face_vhandles.append(self.vhandle[3]) - self.mesh.add_face(face_vhandles) - - # Test setup: - # - # 0 ------ 2 ------ 4 - # \ / \ / - # \ 0 / \ 2 / - # \ / 1 \ / - # 1 ------- 3 - # \ / - # \ 3 / - # \ / - # \ / - # 5 - - ff_it = self.mesh.ff(self.mesh.face_handle(1)) - - self.assertEqual(ff_it.__next__().idx(), 2) - self.assertEqual(ff_it.__next__().idx(), 0) - self.assertEqual(ff_it.__next__().idx(), 3) - self.assertRaises(StopIteration, ff_it.__next__) - - def test_face_face_iter_without_holes(self): - # Add some vertices - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 0, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0))) - - # Add two faces - face_vhandles = [] - - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[1]) - fh1 = self.mesh.add_face(face_vhandles) - - face_vhandles = [] - - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[3]) - face_vhandles.append(self.vhandle[2]) - fh2 = self.mesh.add_face(face_vhandles) - - # Test setup: - # - # 1 -------- 2 - # | f0 / | - # | / f1 | - # 0 -------- 3 - - # Check setup - self.assertEqual(self.mesh.n_vertices(), 4) - self.assertEqual(self.mesh.n_faces(), 2) - - face_iter = self.mesh.ff(fh1) - - # Get the face via the handle - faceHandle1 = face_iter.__next__() - face1 = self.mesh.face(faceHandle1) - - self.assertEqual(faceHandle1.idx(), 1) - - -if __name__ == '__main__': - suite = unittest.TestLoader().loadTestsFromTestCase(TrimeshCirculatorFaceFace) - unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/src/Python/Unittests/test_trimesh_circulator_face_halfedge.py b/src/Python/Unittests/test_trimesh_circulator_face_halfedge.py deleted file mode 100644 index 2da994ed..00000000 --- a/src/Python/Unittests/test_trimesh_circulator_face_halfedge.py +++ /dev/null @@ -1,50 +0,0 @@ -import unittest -import openmesh - -class TriMeshCirculatorFaceHalfEdge(unittest.TestCase): - - def setUp(self): - self.mesh = openmesh.TriMesh() - - # Add some vertices - self.vhandle = [] - - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(3, 0, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(4, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2,-1, 0))) - - # Add four faces - self.mesh.add_face(self.vhandle[0], self.vhandle[1], self.vhandle[2]) - self.mesh.add_face(self.vhandle[2], self.vhandle[1], self.vhandle[3]) - self.mesh.add_face(self.vhandle[2], self.vhandle[3], self.vhandle[4]) - self.mesh.add_face(self.vhandle[1], self.vhandle[5], self.vhandle[3]) - - ''' - Test setup: - 0 ------ 2 ------ 4 - \ / \ / - \ 0 / \ 2 / - \ / 1 \ / - 1 ------- 3 - \ / - \ 3 / - \ / - \ / - 5 - ''' - - def test_face_halfedge_iter_without_holes_increment(self): - # Iterate around face 1 at the middle - fh_it = openmesh.FaceHalfedgeIter(self.mesh, self.mesh.face_handle(1)) - self.assertEqual(fh_it.__next__().idx(), 8) - self.assertEqual(fh_it.__next__().idx(), 3) - self.assertEqual(fh_it.__next__().idx(), 6) - self.assertRaises(StopIteration, fh_it.__next__) - - -if __name__ == '__main__': - suite = unittest.TestLoader().loadTestsFromTestCase(TriMeshCirculatorFaceHalfEdge) - unittest.TextTestRunner(verbosity=2).run(suite) \ No newline at end of file diff --git a/src/Python/Unittests/test_trimesh_circulator_face_vertex.py b/src/Python/Unittests/test_trimesh_circulator_face_vertex.py deleted file mode 100644 index 68161bcf..00000000 --- a/src/Python/Unittests/test_trimesh_circulator_face_vertex.py +++ /dev/null @@ -1,48 +0,0 @@ -import unittest -import openmesh - -class TriMeshCirculatorFaceVertex(unittest.TestCase): - - def setUp(self): - self.mesh = openmesh.TriMesh() - - # Add some vertices - self.vhandle = [] - - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0,-1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2,-1, 0))) - - # Add four faces - self.fh0 = self.mesh.add_face(self.vhandle[0], self.vhandle[1], self.vhandle[2]) - self.mesh.add_face(self.vhandle[1], self.vhandle[3], self.vhandle[4]) - self.mesh.add_face(self.vhandle[0], self.vhandle[3], self.vhandle[1]) - self.mesh.add_face(self.vhandle[2], self.vhandle[1], self.vhandle[4]) - - ''' - Test setup: - 0 ==== 2 - |\ 0 /| - | \ / | - |2 1 3| - | / \ | - |/ 1 \| - 3 ==== 4 - ''' - - def test_face_vertex_iter_without_increment(self): - self.assertEqual(self.fh0.idx(), 0) - - # Iterate around face 0 at the top - fv_it = openmesh.FaceVertexIter(self.mesh, self.fh0) - self.assertEqual(fv_it.__next__().idx(), 0) - self.assertEqual(fv_it.__next__().idx(), 1) - self.assertEqual(fv_it.__next__().idx(), 2) - self.assertRaises(StopIteration, fv_it.__next__) - - -if __name__ == '__main__': - suite = unittest.TestLoader().loadTestsFromTestCase(TriMeshCirculatorFaceVertex) - unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/src/Python/Unittests/test_trimesh_circulator_halfedge_loop.py b/src/Python/Unittests/test_trimesh_circulator_halfedge_loop.py deleted file mode 100644 index 794f7646..00000000 --- a/src/Python/Unittests/test_trimesh_circulator_halfedge_loop.py +++ /dev/null @@ -1,131 +0,0 @@ -import unittest -import openmesh - -class TrimeshCirculatorHalfedgeLoop(unittest.TestCase): - - def setUp(self): - self.mesh = openmesh.TriMesh() - self.vhandle = [] - - def test_halfedge_loop_with_face(self): - # Add some vertices - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(3, 0, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(4, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, -1, 0))) - - # Add four faces - face_vhandles = [] - - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[2]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[3]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[3]) - face_vhandles.append(self.vhandle[4]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[5]) - face_vhandles.append(self.vhandle[3]) - self.mesh.add_face(face_vhandles) - - # Test setup: - # - # edge x => halfedge x/x+1 - # i.e. edge 0 => halfedge 0/1 - # - # 0 --4--- 2 ------ 4 - # \ / \ / - # 0 0 2 6 2 / - # \ / 1 \ / - # 1 ---8--- 3 - # \ / - # \ 3 / - # \ / - # \ / - # 5 - - # Circle around face 1 - hl_it = self.mesh.hl(self.mesh.halfedge_handle(3)) - - self.assertEqual(hl_it.__next__().idx(), 3) - self.assertEqual(hl_it.__next__().idx(), 6) - self.assertEqual(hl_it.__next__().idx(), 8) - self.assertRaises(StopIteration, hl_it.__next__) - - def test_halfedge_loop_without_face(self): - # Add some vertices - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(3, 0, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(4, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, -1, 0))) - - # Add three faces - face_vhandles = [] - - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[2]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[3]) - face_vhandles.append(self.vhandle[4]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[5]) - face_vhandles.append(self.vhandle[3]) - self.mesh.add_face(face_vhandles) - - # Test setup: - # - # H => hole (no face) - # fx => face #x - # edge 0 => halfedge 0/1 - # - # 0 --4--- 2 -10--- 4 - # \ / \ / - # 0 f0 2 6 f2 8 - # \ / H \ / - # 1 ---16---3 - # \ / - # 12 f3 14 - # \ / - # \ / - # 5 - - # Circle around the hole - hl_it = self.mesh.hl(self.mesh.halfedge_handle(3)) - - self.assertEqual(hl_it.__next__().idx(), 3) - self.assertEqual(hl_it.__next__().idx(), 17) - self.assertEqual(hl_it.__next__().idx(), 7) - self.assertRaises(StopIteration, hl_it.__next__) - - -if __name__ == '__main__': - suite = unittest.TestLoader().loadTestsFromTestCase(TrimeshCirculatorHalfedgeLoop) - unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/src/Python/Unittests/test_trimesh_circulator_vertex_edge.py b/src/Python/Unittests/test_trimesh_circulator_vertex_edge.py deleted file mode 100644 index 5792e472..00000000 --- a/src/Python/Unittests/test_trimesh_circulator_vertex_edge.py +++ /dev/null @@ -1,55 +0,0 @@ -import unittest -import openmesh - -class TriMeshCirculatorVertexEdge(unittest.TestCase): - - def setUp(self): - self.mesh = openmesh.TriMesh() - - # Add some vertices - self.vhandle = [] - - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0,-1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2,-1, 0))) - - # Add four faces - self.mesh.add_face(self.vhandle[0], self.vhandle[1], self.vhandle[2]) - self.mesh.add_face(self.vhandle[1], self.vhandle[3], self.vhandle[4]) - self.mesh.add_face(self.vhandle[0], self.vhandle[3], self.vhandle[1]) - self.mesh.add_face(self.vhandle[2], self.vhandle[1], self.vhandle[4]) - - ''' - Test setup: - 0 ==== 2 - |\ 0 /| - | \ / | - |2 1 3| - | / \ | - |/ 1 \| - 3 ==== 4 - ''' - - def test_vertex_edge_iter_without_holes_increment(self): - # Iterate around vertex 1 at the middle - ve_it = openmesh.VertexEdgeIter(self.mesh, self.vhandle[1]) - self.assertEqual(ve_it.__next__().idx(), 5) - self.assertEqual(ve_it.__next__().idx(), 3) - self.assertEqual(ve_it.__next__().idx(), 0) - self.assertEqual(ve_it.__next__().idx(), 1) - self.assertRaises(StopIteration, ve_it.__next__) - - def test_vertex_edge_iter_boundary_increment(self): - # Iterate around vertex 2 at the boundary - ve_it = openmesh.VertexEdgeIter(self.mesh, self.vhandle[2]) - self.assertEqual(ve_it.__next__().idx(), 7) - self.assertEqual(ve_it.__next__().idx(), 1) - self.assertEqual(ve_it.__next__().idx(), 2) - self.assertRaises(StopIteration, ve_it.__next__) - - -if __name__ == '__main__': - suite = unittest.TestLoader().loadTestsFromTestCase(TriMeshCirculatorVertexEdge) - unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/src/Python/Unittests/test_trimesh_circulator_vertex_face.py b/src/Python/Unittests/test_trimesh_circulator_vertex_face.py deleted file mode 100644 index 4a58f0f7..00000000 --- a/src/Python/Unittests/test_trimesh_circulator_vertex_face.py +++ /dev/null @@ -1,93 +0,0 @@ -import unittest -import openmesh - -class TriMeshCirculatorVertexFace(unittest.TestCase): - - def setUp(self): - self.mesh = openmesh.TriMesh() - - # Add some vertices - self.vhandle = [] - - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0,-1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2,-1, 0))) - - def test_vertex_face_iter_with_holes_increment(self): - # Add two faces - self.mesh.add_face(self.vhandle[0], self.vhandle[1], self.vhandle[2]) - self.mesh.add_face(self.vhandle[1], self.vhandle[3], self.vhandle[4]) - - ''' - Test setup: - 0 ==== 2 - \ / - \ / - 1 - / \ - / \ - 3 ==== 4 - ''' - - # Iterate around vertex 1 at the middle (with holes in between) - vf_it = openmesh.VertexFaceIter(self.mesh, self.vhandle[1]) - self.assertEqual(vf_it.__next__().idx(), 0) - self.assertEqual(vf_it.__next__().idx(), 1) - self.assertRaises(StopIteration, vf_it.__next__) - - def test_vertex_face_iter_without_holes_increment(self): - # Add four faces - self.mesh.add_face(self.vhandle[0], self.vhandle[1], self.vhandle[2]) - self.mesh.add_face(self.vhandle[1], self.vhandle[3], self.vhandle[4]) - self.mesh.add_face(self.vhandle[0], self.vhandle[3], self.vhandle[1]) - self.mesh.add_face(self.vhandle[2], self.vhandle[1], self.vhandle[4]) - - ''' - Test setup: - 0 ==== 2 - |\ 0 /| - | \ / | - |2 1 3| - | / \ | - |/ 1 \| - 3 ==== 4 - ''' - - # Iterate around vertex 1 at the middle (without holes in between) - vf_it = openmesh.VertexFaceIter(self.mesh, self.vhandle[1]) - self.assertEqual(vf_it.__next__().idx(), 3) - self.assertEqual(vf_it.__next__().idx(), 1) - self.assertEqual(vf_it.__next__().idx(), 2) - self.assertEqual(vf_it.__next__().idx(), 0) - self.assertRaises(StopIteration, vf_it.__next__) - - def test_vertex_face_iter_boundary_increment(self): - # Add four faces - self.mesh.add_face(self.vhandle[0], self.vhandle[1], self.vhandle[2]) - self.mesh.add_face(self.vhandle[1], self.vhandle[3], self.vhandle[4]) - self.mesh.add_face(self.vhandle[0], self.vhandle[3], self.vhandle[1]) - self.mesh.add_face(self.vhandle[2], self.vhandle[1], self.vhandle[4]) - - ''' - Test setup: - 0 ==== 2 - |\ 0 /| - | \ / | - |2 1 3| - | / \ | - |/ 1 \| - 3 ==== 4 - ''' - - # Iterate around vertex 2 at the boundary (without holes in between) - vf_it = openmesh.VertexFaceIter(self.mesh, self.vhandle[2]) - self.assertEqual(vf_it.__next__().idx(), 3) - self.assertEqual(vf_it.__next__().idx(), 0) - self.assertRaises(StopIteration, vf_it.__next__) - - -if __name__ == '__main__': - suite = unittest.TestLoader().loadTestsFromTestCase(TriMeshCirculatorVertexFace) - unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/src/Python/Unittests/test_trimesh_circulator_vertex_ihalfedge.py b/src/Python/Unittests/test_trimesh_circulator_vertex_ihalfedge.py deleted file mode 100644 index 96b0950f..00000000 --- a/src/Python/Unittests/test_trimesh_circulator_vertex_ihalfedge.py +++ /dev/null @@ -1,80 +0,0 @@ -import unittest -import openmesh - -class TriMeshCirculatorVertexIHalfEdge(unittest.TestCase): - - def setUp(self): - self.mesh = openmesh.TriMesh() - - # Add some vertices - self.vhandle = [] - - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0,-1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2,-1, 0))) - - # Add four faces - self.mesh.add_face(self.vhandle[0], self.vhandle[1], self.vhandle[2]) - self.mesh.add_face(self.vhandle[1], self.vhandle[3], self.vhandle[4]) - self.mesh.add_face(self.vhandle[0], self.vhandle[3], self.vhandle[1]) - self.mesh.add_face(self.vhandle[2], self.vhandle[1], self.vhandle[4]) - - ''' - Test setup: - 0 ==== 2 - |\ 0 /| - | \ / | - |2 1 3| - | / \ | - |/ 1 \| - 3 ==== 4 - Starting halfedge is 1->4 - ''' - - def test_vertex_incoming_halfedge_without_holes_increment(self): - # Iterate around vertex 1 at the middle - vih_it = openmesh.VertexIHalfedgeIter(self.mesh, self.vhandle[1]) - heh = vih_it.__next__() - self.assertEqual(heh.idx(), 10) - self.assertEqual(self.mesh.face_handle(heh).idx(), 1) - heh = vih_it.__next__() - self.assertEqual(heh.idx(), 7) - self.assertEqual(self.mesh.face_handle(heh).idx(), 2) - heh = vih_it.__next__() - self.assertEqual(heh.idx(), 0) - self.assertEqual(self.mesh.face_handle(heh).idx(), 0) - heh = vih_it.__next__() - self.assertEqual(heh.idx(), 3) - self.assertEqual(self.mesh.face_handle(heh).idx(), 3) - self.assertRaises(StopIteration, vih_it.__next__) - - def test_vertex_incoming_halfedge_boundary_increment(self): - # Iterate around vertex 2 at the boundary - vih_it = openmesh.VertexIHalfedgeIter(self.mesh, self.vhandle[2]) - heh = vih_it.__next__() - self.assertEqual(heh.idx(), 14) - self.assertEqual(self.mesh.face_handle(heh).idx(), 3) - heh = vih_it.__next__() - self.assertEqual(heh.idx(), 2) - self.assertEqual(self.mesh.face_handle(heh).idx(), 0) - heh = vih_it.__next__() - self.assertEqual(heh.idx(), 5) - self.assertEqual(self.mesh.face_handle(heh).idx(), -1) - self.assertRaises(StopIteration, vih_it.__next__) - - def test_vertex_incoming_halfedge_dereference_increment(self): - # Iterate around vertex 1 at the middle - vih_it = openmesh.VertexIHalfedgeIter(self.mesh, self.vhandle[1]) - heh = vih_it.__next__() - eh = self.mesh.edge_handle(heh) - vh = self.mesh.to_vertex_handle(heh) - self.assertEqual(heh.idx(), 10) - self.assertEqual(eh.idx(), 5) - self.assertEqual(vh.idx(), 1) - - -if __name__ == '__main__': - suite = unittest.TestLoader().loadTestsFromTestCase(TriMeshCirculatorVertexIHalfEdge) - unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/src/Python/Unittests/test_trimesh_circulator_vertex_ohalfedge.py b/src/Python/Unittests/test_trimesh_circulator_vertex_ohalfedge.py deleted file mode 100644 index 2d68a6be..00000000 --- a/src/Python/Unittests/test_trimesh_circulator_vertex_ohalfedge.py +++ /dev/null @@ -1,80 +0,0 @@ -import unittest -import openmesh - -class TriMeshCirculatorVertexOHalfEdge(unittest.TestCase): - - def setUp(self): - self.mesh = openmesh.TriMesh() - - # Add some vertices - self.vhandle = [] - - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0,-1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2,-1, 0))) - - # Add four faces - self.mesh.add_face(self.vhandle[0], self.vhandle[1], self.vhandle[2]) - self.mesh.add_face(self.vhandle[1], self.vhandle[3], self.vhandle[4]) - self.mesh.add_face(self.vhandle[0], self.vhandle[3], self.vhandle[1]) - self.mesh.add_face(self.vhandle[2], self.vhandle[1], self.vhandle[4]) - - ''' - Test setup: - 0 ==== 2 - |\ 0 /| - | \ / | - |2 1 3| - | / \ | - |/ 1 \| - 3 ==== 4 - Starting halfedge is 1->4 - ''' - - def test_vertex_outgoing_halfedge_without_holes_increment(self): - # Iterate around vertex 1 at the middle - voh_it = openmesh.VertexOHalfedgeIter(self.mesh, self.vhandle[1]) - heh = voh_it.__next__() - self.assertEqual(heh.idx(), 11) - self.assertEqual(self.mesh.face_handle(heh).idx(), 3) - heh = voh_it.__next__() - self.assertEqual(heh.idx(), 6) - self.assertEqual(self.mesh.face_handle(heh).idx(), 1) - heh = voh_it.__next__() - self.assertEqual(heh.idx(), 1) - self.assertEqual(self.mesh.face_handle(heh).idx(), 2) - heh = voh_it.__next__() - self.assertEqual(heh.idx(), 2) - self.assertEqual(self.mesh.face_handle(heh).idx(), 0) - self.assertRaises(StopIteration, voh_it.__next__) - - def test_vertex_outgoing_halfedge_boundary_increment(self): - # Iterate around vertex 2 at the boundary - voh_it = openmesh.VertexOHalfedgeIter(self.mesh, self.vhandle[2]) - heh = voh_it.__next__() - self.assertEqual(heh.idx(), 15) - self.assertEqual(self.mesh.face_handle(heh).idx(), -1) - heh = voh_it.__next__() - self.assertEqual(heh.idx(), 3) - self.assertEqual(self.mesh.face_handle(heh).idx(), 3) - heh = voh_it.__next__() - self.assertEqual(heh.idx(), 4) - self.assertEqual(self.mesh.face_handle(heh).idx(), 0) - self.assertRaises(StopIteration, voh_it.__next__) - - def test_vertex_outgoing_halfedge_dereference_increment(self): - # Iterate around vertex 1 at the middle - voh_it = openmesh.VertexOHalfedgeIter(self.mesh, self.vhandle[1]) - heh = voh_it.__next__() - eh = self.mesh.edge_handle(heh) - vh = self.mesh.to_vertex_handle(heh) - self.assertEqual(heh.idx(), 11) - self.assertEqual(eh.idx(), 5) - self.assertEqual(vh.idx(), 4) - - -if __name__ == '__main__': - suite = unittest.TestLoader().loadTestsFromTestCase(TriMeshCirculatorVertexOHalfEdge) - unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/src/Python/Unittests/test_trimesh_circulator_vertex_vertex.py b/src/Python/Unittests/test_trimesh_circulator_vertex_vertex.py deleted file mode 100644 index c0d10d7d..00000000 --- a/src/Python/Unittests/test_trimesh_circulator_vertex_vertex.py +++ /dev/null @@ -1,56 +0,0 @@ -import unittest -import openmesh - -class TriMeshCirculatorVertexVertex(unittest.TestCase): - - def setUp(self): - self.mesh = openmesh.TriMesh() - - # Add some vertices - self.vhandle = [] - - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0,-1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2,-1, 0))) - - # Add four faces - self.mesh.add_face(self.vhandle[0], self.vhandle[1], self.vhandle[2]) - self.mesh.add_face(self.vhandle[1], self.vhandle[3], self.vhandle[4]) - self.mesh.add_face(self.vhandle[0], self.vhandle[3], self.vhandle[1]) - self.mesh.add_face(self.vhandle[2], self.vhandle[1], self.vhandle[4]) - - ''' - Test setup: - 0 ==== 2 - |\ 0 /| - | \ / | - |2 1 3| - | / \ | - |/ 1 \| - 3 ==== 4 - Starting vertex is 1->4 - ''' - - def test_vertex_vertex_increment(self): - # Iterate around vertex 1 at the middle - vv_it = openmesh.VertexVertexIter(self.mesh, self.vhandle[1]) - self.assertEqual(vv_it.__next__().idx(), 4) - self.assertEqual(vv_it.__next__().idx(), 3) - self.assertEqual(vv_it.__next__().idx(), 0) - self.assertEqual(vv_it.__next__().idx(), 2) - self.assertRaises(StopIteration, vv_it.__next__) - - def test_vertex_vertex_boundary_increment(self): - # Iterate around vertex 2 at the boundary - vv_it = openmesh.VertexVertexIter(self.mesh, self.vhandle[2]) - self.assertEqual(vv_it.__next__().idx(), 4) - self.assertEqual(vv_it.__next__().idx(), 1) - self.assertEqual(vv_it.__next__().idx(), 0) - self.assertRaises(StopIteration, vv_it.__next__) - - -if __name__ == '__main__': - suite = unittest.TestLoader().loadTestsFromTestCase(TriMeshCirculatorVertexVertex) - unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/src/Python/Unittests/test_trimesh_collapse.py b/src/Python/Unittests/test_trimesh_collapse.py deleted file mode 100644 index 8c3a48c8..00000000 --- a/src/Python/Unittests/test_trimesh_collapse.py +++ /dev/null @@ -1,516 +0,0 @@ -import unittest -import openmesh - -class Collapse(unittest.TestCase): - - def setUp(self): - self.mesh = openmesh.TriMesh() - self.vhandle = [] - - def test_collapse_quad_with_center(self): - - # 0--------1 - # |\ /| - # | \ / | - # | \ / | - # | 2 | - # | / \ | - # | / \ | - # 3--------4 - - # Add some vertices - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 0, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, 0, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 2, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, 2, 0))) - - # Add four faces - face_vhandles = [] - - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[1]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[3]) - face_vhandles.append(self.vhandle[2]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - - face_vhandles.append(self.vhandle[4]) - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[3]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - - face_vhandles.append(self.vhandle[4]) - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[2]) - self.mesh.add_face(face_vhandles) - - self.mesh.request_vertex_status() - self.mesh.request_edge_status() - self.mesh.request_face_status() - - # Get the halfedge - v2v1 = self.mesh.find_halfedge(self.vhandle[2], self.vhandle[1]) - - self.assertTrue(v2v1.is_valid()) - self.assertTrue(self.mesh.is_collapse_ok(v2v1)) - - # Execute it as a crash test - self.mesh.collapse(v2v1) - - def test_collapse_tetrahedron_complex(self): - # Add some vertices - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 0, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0))) - - # Add four faces - face_vhandles = [] - - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[2]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[3]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[3]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - - face_vhandles.append(self.vhandle[3]) - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[0]) - self.mesh.add_face(face_vhandles) - - self.mesh.request_vertex_status() - self.mesh.request_edge_status() - self.mesh.request_face_status() - - v0v1 = self.mesh.halfedge_handle(0) - v1v0 = self.mesh.opposite_halfedge_handle(v0v1) - - v1vL = self.mesh.next_halfedge_handle(v0v1) - vLv1 = self.mesh.opposite_halfedge_handle(v1vL) - vLv0 = self.mesh.next_halfedge_handle(v1vL) - v0vL = self.mesh.opposite_halfedge_handle(vLv0) - - vLvR = self.mesh.next_halfedge_handle(v0vL) - vRvL = self.mesh.opposite_halfedge_handle(vLvR) - - v0vR = self.mesh.next_halfedge_handle(v1v0) - vRv0 = self.mesh.opposite_halfedge_handle(v0vR) - vRv1 = self.mesh.next_halfedge_handle(v0vR) - v1vR = self.mesh.opposite_halfedge_handle(vRv1) - - v0 = self.mesh.from_vertex_handle(v0v1) - v1 = self.mesh.to_vertex_handle(v0v1) - vL = self.mesh.to_vertex_handle(self.mesh.next_halfedge_handle(v0v1)) - vR = self.mesh.to_vertex_handle(self.mesh.next_halfedge_handle(v1v0)) - - # =================================================================== - # Check preconditions - # =================================================================== - - self.assertTrue(self.mesh.is_collapse_ok(v0v1)) - self.assertTrue(self.mesh.is_collapse_ok(v1v0)) - - # Test the Vertex indices - self.assertEqual(v0.idx(), 0) - self.assertEqual(v1.idx(), 1) - self.assertEqual(vL.idx(), 2) - self.assertEqual(vR.idx(), 3) - - # Check the halfedges - self.assertEqual(v0v1.idx(), 0) - self.assertEqual(v1v0.idx(), 1) - - self.assertEqual(v1vL.idx(), 2) - self.assertEqual(vLv1.idx(), 3) - self.assertEqual(vLv0.idx(), 4) - self.assertEqual(v0vL.idx(), 5) - - self.assertEqual(vLvR.idx(), 6) - self.assertEqual(vRvL.idx(), 7) - - self.assertEqual(vRv0.idx(), 8) - self.assertEqual(v0vR.idx(), 9) - - self.assertEqual(v1vR.idx(), 10) - self.assertEqual(vRv1.idx(), 11) - - # =================================================================== - # Execute collapse - # =================================================================== - - self.mesh.collapse(v0v1) - - # =================================================================== - # Check configuration afterwards - # =================================================================== - - # Now the configuration should look like this: - # The numbers at the side denote the halfedges - # 1 - # / \ - # / \ - # // \\ - # 3/2 11\10 - # // \\ - # / 6--> \ - # 2 ----------- 3 - # <--7 - - self.assertEqual(self.mesh.n_faces(), 4) - - # Check if the right vertices got deleted - self.assertTrue(self.mesh.status(self.mesh.face_handle(0)).deleted()) - self.assertFalse(self.mesh.status(self.mesh.face_handle(1)).deleted()) - self.assertFalse(self.mesh.status(self.mesh.face_handle(2)).deleted()) - self.assertTrue(self.mesh.status(self.mesh.face_handle(3)).deleted()) - - # Check the vertices of the two remaining faces - fh_1 = self.mesh.face_handle(1) - fh_2 = self.mesh.face_handle(2) - - fv_it = self.mesh.fv(fh_1) - - self.assertTrue(fv_it.__next__().idx(), 1) - self.assertTrue(fv_it.__next__().idx(), 2) - self.assertTrue(fv_it.__next__().idx(), 3) - - fv_it = self.mesh.fv(fh_2) - - self.assertTrue(fv_it.__next__().idx(), 2) - self.assertTrue(fv_it.__next__().idx(), 1) - self.assertTrue(fv_it.__next__().idx(), 3) - - # Get the first halfedge of face 1 - fh_1_he = self.mesh.halfedge_handle(fh_1) - - self.assertEqual(fh_1_he.idx(), 11) - self.assertEqual(self.mesh.to_vertex_handle(fh_1_he).idx(), 1) - - next = self.mesh.next_halfedge_handle(fh_1_he) - self.assertEqual(next.idx(), 2) - self.assertEqual(self.mesh.to_vertex_handle(next).idx(), 2) - - next = self.mesh.next_halfedge_handle(next) - self.assertEqual(next.idx(), 6) - self.assertEqual(self.mesh.to_vertex_handle(next).idx(), 3) - - # Get the first halfedge of face 2 - fh_2_he = self.mesh.halfedge_handle(fh_2) - - self.assertEqual(fh_2_he.idx(), 7) - self.assertEqual(self.mesh.to_vertex_handle(fh_2_he).idx(), 2) - - next = self.mesh.next_halfedge_handle(fh_2_he) - self.assertEqual(next.idx(), 3) - self.assertEqual(self.mesh.to_vertex_handle(next).idx(), 1) - - next = self.mesh.next_halfedge_handle(next) - self.assertEqual(next.idx(), 10) - self.assertEqual(self.mesh.to_vertex_handle(next).idx(), 3) - - # Vertex 1 outgoing - voh_it = self.mesh.voh(self.mesh.vertex_handle(1)) - self.assertEqual(voh_it.__next__().idx(), 10) - self.assertEqual(voh_it.__next__().idx(), 2) - self.assertRaises(StopIteration, voh_it.__next__) - - # Vertex 2 outgoing - voh_it = self.mesh.voh(self.mesh.vertex_handle(2)) - self.assertEqual(voh_it.__next__().idx(), 3) - self.assertEqual(voh_it.__next__().idx(), 6) - self.assertRaises(StopIteration, voh_it.__next__) - - # Vertex 2 outgoing - voh_it = self.mesh.voh(self.mesh.vertex_handle(3)) - self.assertEqual(voh_it.__next__().idx(), 11) - self.assertEqual(voh_it.__next__().idx(), 7) - self.assertRaises(StopIteration, voh_it.__next__) - - # =================================================================== - # Cleanup - # =================================================================== - self.mesh.garbage_collection() - - # =================================================================== - # Check configuration afterwards - # =================================================================== - - # Now the configuration should look like this: - # The numbers at the side denote the halfedges - # 0 - # / \ - # / \ - # // \\ - # 4/5 0\1 - # // \\ - # / 3--> \ - # 2 ----------- 1 - # <--2 - - self.assertEqual(self.mesh.n_faces(), 2) - - # Check the vertices of the two remaining faces - fh_0 = self.mesh.face_handle(0) - fh_1 = self.mesh.face_handle(1) - - fv_it = self.mesh.fv(fh_0) - - self.assertEqual(fv_it.__next__().idx(), 2) - self.assertEqual(fv_it.__next__().idx(), 1) - self.assertEqual(fv_it.__next__().idx(), 0) - - fv_it = self.mesh.fv(fh_1) - - self.assertEqual(fv_it.__next__().idx(), 1) - self.assertEqual(fv_it.__next__().idx(), 2) - self.assertEqual(fv_it.__next__().idx(), 0) - - # Get the first halfedge of face 1 - fh_0_he = self.mesh.halfedge_handle(fh_0) - - self.assertEqual(fh_0_he.idx(), 5) - self.assertEqual(self.mesh.to_vertex_handle(fh_0_he).idx(), 2) - - next = self.mesh.next_halfedge_handle(fh_0_he) - self.assertEqual(next.idx(), 3) - self.assertEqual(self.mesh.to_vertex_handle(next).idx(), 1) - - next = self.mesh.next_halfedge_handle(next) - self.assertEqual(next.idx(), 0) - self.assertEqual(self.mesh.to_vertex_handle(next).idx(), 0) - - # Get the first halfedge of face 1 - fh_1_he = self.mesh.halfedge_handle(fh_1) - - self.assertEqual(fh_1_he.idx(), 1) - self.assertEqual(self.mesh.to_vertex_handle(fh_1_he).idx(), 1) - - next = self.mesh.next_halfedge_handle(fh_1_he) - self.assertEqual(next.idx(), 2) - self.assertEqual(self.mesh.to_vertex_handle(next).idx(), 2) - - next = self.mesh.next_halfedge_handle(next) - self.assertEqual(next.idx(), 4) - self.assertEqual(self.mesh.to_vertex_handle(next).idx(), 0) - - # Vertex 0 outgoing - voh_it = self.mesh.voh(self.mesh.vertex_handle(0)) - self.assertEqual(voh_it.__next__().idx(), 1) - self.assertEqual(voh_it.__next__().idx(), 5) - self.assertRaises(StopIteration, voh_it.__next__) - - # Vertex 1 outgoing - voh_it = self.mesh.voh(self.mesh.vertex_handle(1)) - self.assertEqual(voh_it.__next__().idx(), 0) - self.assertEqual(voh_it.__next__().idx(), 2) - self.assertRaises(StopIteration, voh_it.__next__) - - # Vertex 2 outgoing - voh_it = self.mesh.voh(self.mesh.vertex_handle(2)) - self.assertEqual(voh_it.__next__().idx(), 3) - self.assertEqual(voh_it.__next__().idx(), 4) - self.assertRaises(StopIteration, voh_it.__next__) - - self.assertFalse(self.mesh.is_collapse_ok(self.mesh.halfedge_handle(0))) - self.assertFalse(self.mesh.is_collapse_ok(self.mesh.halfedge_handle(1))) - self.assertFalse(self.mesh.is_collapse_ok(self.mesh.halfedge_handle(2))) - self.assertFalse(self.mesh.is_collapse_ok(self.mesh.halfedge_handle(3))) - self.assertFalse(self.mesh.is_collapse_ok(self.mesh.halfedge_handle(4))) - self.assertFalse(self.mesh.is_collapse_ok(self.mesh.halfedge_handle(5))) - - def test_collapse_tetrahedron(self): - # Add some vertices - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 0, 0, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, 0, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 0, -1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 0, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, 0, 0))) - - # Add six faces - face_vhandles = [] - - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[4]) - face_vhandles.append(self.vhandle[2]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - - face_vhandles.append(self.vhandle[3]) - face_vhandles.append(self.vhandle[4]) - face_vhandles.append(self.vhandle[0]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[4]) - face_vhandles.append(self.vhandle[3]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[0]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[3]) - self.mesh.add_face(face_vhandles) - - self.mesh.request_vertex_status() - self.mesh.request_edge_status() - self.mesh.request_face_status() - - # ============================================= - # Collapse halfedge from 0 to 4 - # ============================================= - - heh_collapse1 = self.mesh.halfedge_handle(0) - - self.assertEqual(self.mesh.to_vertex_handle(heh_collapse1).idx(), 4) - self.assertEqual(self.mesh.from_vertex_handle(heh_collapse1).idx(), 0) - - self.assertTrue(self.mesh.is_collapse_ok(heh_collapse1)) - self.mesh.collapse(heh_collapse1) - - heh_collapse2 = self.mesh.halfedge_handle(2) - - self.assertEqual(self.mesh.to_vertex_handle(heh_collapse2).idx(), 2) - self.assertEqual(self.mesh.from_vertex_handle(heh_collapse2).idx(), 4) - - self.assertTrue(self.mesh.is_collapse_ok(heh_collapse2)) - self.mesh.collapse(heh_collapse2) - - heh_collapse3 = self.mesh.halfedge_handle(6) - - self.assertEqual(self.mesh.to_vertex_handle(heh_collapse3).idx(), 2) - self.assertEqual(self.mesh.from_vertex_handle(heh_collapse3).idx(), 3) - - self.assertFalse(self.mesh.is_collapse_ok(heh_collapse3)) - - def test_large_collapse_halfedge(self): - # Add some vertices - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 0, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, 0, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 2, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 0, -1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 2, -1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, 0, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 3, 0, 0))) - - # Add six faces - face_vhandles = [] - - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[5]) - face_vhandles.append(self.vhandle[1]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[5]) - face_vhandles.append(self.vhandle[3]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[2]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[3]) - face_vhandles.append(self.vhandle[4]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[4]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[4]) - face_vhandles.append(self.vhandle[6]) - self.mesh.add_face(face_vhandles) - - # Test setup: - # 0 ==== 2 - # / \ /|\ - # / \ / | \ - # 5 --- 1 | 6 - # \ / \ | / - # \ / \|/ - # 3 ==== 4 - - # Request the status bits - self.mesh.request_vertex_status() - self.mesh.request_edge_status() - self.mesh.request_face_status() - - # ============================================= - # Collapse halfedge from 1 to 4 - # ============================================= - - heh_collapse = openmesh.HalfedgeHandle() - - for he in self.mesh.halfedges(): - if self.mesh.from_vertex_handle(he).idx() == 1 and self.mesh.to_vertex_handle(he).idx() == 4: - heh_collapse = he - - # Check our halfedge - self.assertEqual(self.mesh.to_vertex_handle(heh_collapse).idx(), 4) - self.assertEqual(self.mesh.from_vertex_handle(heh_collapse).idx(), 1) - self.assertTrue(self.mesh.is_collapse_ok(heh_collapse)) - - # Remember the end vertices - vh_from = self.mesh.from_vertex_handle(heh_collapse) - vh_to = self.mesh.to_vertex_handle(heh_collapse) - - # Collapse it - self.mesh.collapse(heh_collapse) - - self.assertTrue(self.mesh.status(vh_from).deleted()) - self.assertFalse(self.mesh.status(vh_to).deleted()) - - -if __name__ == '__main__': - suite = unittest.TestLoader().loadTestsFromTestCase(Collapse) - unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/src/Python/Unittests/test_trimesh_garbage_collection.py b/src/Python/Unittests/test_trimesh_garbage_collection.py deleted file mode 100644 index 07c820b2..00000000 --- a/src/Python/Unittests/test_trimesh_garbage_collection.py +++ /dev/null @@ -1,168 +0,0 @@ -import unittest -import openmesh - -class TriMeshGarbageCollection(unittest.TestCase): - - def setUp(self): - self.mesh = openmesh.TriMesh() - - self.mesh.request_vertex_status() - self.mesh.request_edge_status() - self.mesh.request_halfedge_status() - self.mesh.request_face_status() - - # Add some vertices - self.vhandle = [] - - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, -1, 1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, -1, 1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, 1, 1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, 1, 1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, -1, -1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, -1, -1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, 1, -1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, 1, -1))) - - # Add six faces to form a cube - self.mesh.add_face(self.vhandle[0], self.vhandle[1], self.vhandle[3]) - self.mesh.add_face(self.vhandle[1], self.vhandle[2], self.vhandle[3]) - self.mesh.add_face(self.vhandle[7], self.vhandle[6], self.vhandle[5]) - self.mesh.add_face(self.vhandle[7], self.vhandle[5], self.vhandle[4]) - self.mesh.add_face(self.vhandle[1], self.vhandle[0], self.vhandle[4]) - self.mesh.add_face(self.vhandle[1], self.vhandle[4], self.vhandle[5]) - self.mesh.add_face(self.vhandle[2], self.vhandle[1], self.vhandle[5]) - self.mesh.add_face(self.vhandle[2], self.vhandle[5], self.vhandle[6]) - self.mesh.add_face(self.vhandle[3], self.vhandle[2], self.vhandle[6]) - self.mesh.add_face(self.vhandle[3], self.vhandle[6], self.vhandle[7]) - self.mesh.add_face(self.vhandle[0], self.vhandle[3], self.vhandle[7]) - self.mesh.add_face(self.vhandle[0], self.vhandle[7], self.vhandle[4]) - - # Test setup: - # - # 3 ======== 2 - # / /| - # / / | z - # 0 ======== 1 | | - # | | | | y - # | 7 | 6 | / - # | | / | / - # | |/ |/ - # 4 ======== 5 -------> x - - def test_standard_garbage_collection(self): - # Check setup - self.assertEqual(self.mesh.n_vertices(), 8) - self.assertEqual(self.mesh.n_faces(), 12) - - self.mesh.delete_vertex(self.vhandle[0]) - - # Check setup - self.assertEqual(self.mesh.n_vertices(), 8) - self.assertEqual(self.mesh.n_faces(), 12) - - self.mesh.garbage_collection() - - # Check setup - self.assertEqual(self.mesh.n_vertices(), 7) - self.assertEqual(self.mesh.n_faces(), 8) - - def test_tracked_garbage_collection(self): - # Check setup - self.assertEqual(self.mesh.n_vertices(), 8) - self.assertEqual(self.mesh.n_faces(), 12) - - #================================================== - # Create lists containing the current handles - #================================================== - - vertexHandles = [] - for v in self.mesh.vertices(): - vertexHandles.append(v) - - halfedgeHandles = [] - for he in self.mesh.halfedges(): - halfedgeHandles.append(he) - - faceHandles = [] - for f in self.mesh.faces(): - faceHandles.append(f) - - # Deleting vertex 0 - self.mesh.delete_vertex(self.vhandle[0]) - - # Check setup - self.assertEqual(self.mesh.n_vertices(), 8) - self.assertEqual(self.mesh.n_faces(), 12) - - self.mesh.garbage_collection(vertexHandles, halfedgeHandles, faceHandles, True, True, True) - - # Check setup - self.assertEqual(self.mesh.n_vertices(), 7) - self.assertEqual(self.mesh.n_faces(), 8) - - # Check setup of vertices - self.assertEqual(vertexHandles[0].idx(), -1) - self.assertEqual(vertexHandles[1].idx(), 1) - self.assertEqual(vertexHandles[2].idx(), 2) - self.assertEqual(vertexHandles[3].idx(), 3) - self.assertEqual(vertexHandles[4].idx(), 4) - self.assertEqual(vertexHandles[5].idx(), 5) - self.assertEqual(vertexHandles[6].idx(), 6) - self.assertEqual(vertexHandles[7].idx(), 0) - - # Check setup of halfedge handles - self.assertEqual(halfedgeHandles[0 ].idx(), -1) - self.assertEqual(halfedgeHandles[1 ].idx(), -1) - self.assertEqual(halfedgeHandles[2 ].idx(), 2) - self.assertEqual(halfedgeHandles[3 ].idx(), 3) - self.assertEqual(halfedgeHandles[4 ].idx(), -1) - self.assertEqual(halfedgeHandles[5 ].idx(), -1) - self.assertEqual(halfedgeHandles[6 ].idx(), 6) - self.assertEqual(halfedgeHandles[7 ].idx(), 7) - self.assertEqual(halfedgeHandles[8 ].idx(), 8) - self.assertEqual(halfedgeHandles[9 ].idx(), 9) - self.assertEqual(halfedgeHandles[10].idx(), 10) - self.assertEqual(halfedgeHandles[11].idx(), 11) - self.assertEqual(halfedgeHandles[12].idx(), 12) - self.assertEqual(halfedgeHandles[13].idx(), 13) - self.assertEqual(halfedgeHandles[14].idx(), 14) - self.assertEqual(halfedgeHandles[15].idx(), 15) - self.assertEqual(halfedgeHandles[16].idx(), 16) - self.assertEqual(halfedgeHandles[17].idx(), 17) - self.assertEqual(halfedgeHandles[18].idx(), 18) - self.assertEqual(halfedgeHandles[19].idx(), 19) - self.assertEqual(halfedgeHandles[20].idx(), -1) - self.assertEqual(halfedgeHandles[21].idx(), -1) - self.assertEqual(halfedgeHandles[22].idx(), 22) - self.assertEqual(halfedgeHandles[23].idx(), 23) - self.assertEqual(halfedgeHandles[24].idx(), 24) - self.assertEqual(halfedgeHandles[25].idx(), 25) - self.assertEqual(halfedgeHandles[26].idx(), 26) - self.assertEqual(halfedgeHandles[27].idx(), 27) - self.assertEqual(halfedgeHandles[28].idx(), 20) - self.assertEqual(halfedgeHandles[29].idx(), 21) - self.assertEqual(halfedgeHandles[30].idx(), 4) - self.assertEqual(halfedgeHandles[31].idx(), 5) - self.assertEqual(halfedgeHandles[32].idx(), 0) - self.assertEqual(halfedgeHandles[33].idx(), 1) - self.assertEqual(halfedgeHandles[34].idx(), -1) - self.assertEqual(halfedgeHandles[35].idx(), -1) - - # Check setup of faces - self.assertEqual(faceHandles[0 ].idx(), -1) - self.assertEqual(faceHandles[1 ].idx(), 1) - self.assertEqual(faceHandles[2 ].idx(), 2) - self.assertEqual(faceHandles[3 ].idx(), 3) - self.assertEqual(faceHandles[4 ].idx(), -1) - self.assertEqual(faceHandles[5 ].idx(), 5) - self.assertEqual(faceHandles[6 ].idx(), 6) - self.assertEqual(faceHandles[7 ].idx(), 7) - self.assertEqual(faceHandles[8 ].idx(), 4) - self.assertEqual(faceHandles[9 ].idx(), 0) - self.assertEqual(faceHandles[10].idx(), -1) - self.assertEqual(faceHandles[11].idx(), -1) - - -if __name__ == '__main__': - suite = unittest.TestLoader().loadTestsFromTestCase(TriMeshGarbageCollection) - unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/src/Python/Unittests/test_trimesh_iterators.py b/src/Python/Unittests/test_trimesh_iterators.py deleted file mode 100755 index 6bd48c35..00000000 --- a/src/Python/Unittests/test_trimesh_iterators.py +++ /dev/null @@ -1,396 +0,0 @@ -import unittest -import openmesh - -class TriMeshIterators(unittest.TestCase): - - def setUp(self): - self.mesh = openmesh.TriMesh() - self.vhandle = [] - - def test_vertex_iter(self): - # Add some vertices - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 0, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0))) - - # Add two faces - self.mesh.add_face(self.vhandle[2], self.vhandle[1], self.vhandle[0]) - self.mesh.add_face(self.vhandle[2], self.vhandle[0], self.vhandle[3]) - - # Test setup: - # 1 === 2 - # | / | - # | / | - # | / | - # 0 === 3 - - v_it = self.mesh.vertices() - - self.assertEqual(v_it.__next__().idx(), 0) - self.assertEqual(v_it.__next__().idx(), 1) - self.assertEqual(v_it.__next__().idx(), 2) - self.assertEqual(v_it.__next__().idx(), 3) - - self.assertRaises(StopIteration, v_it.__next__) - - def test_vertex_iter_start_position(self): - # Add some vertices - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 0, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0))) - - # Add two faces - self.mesh.add_face(self.vhandle[2], self.vhandle[1], self.vhandle[0]) - self.mesh.add_face(self.vhandle[2], self.vhandle[0], self.vhandle[3]) - - # Test setup: - # 1 === 2 - # | / | - # | / | - # | / | - # 0 === 3 - - v_it = openmesh.VertexIter(self.mesh, self.mesh.vertex_handle(2)) - - self.assertEqual(v_it.__next__().idx(), 2) - self.assertEqual(v_it.__next__().idx(), 3) - - self.assertRaises(StopIteration, v_it.__next__) - - def test_edge_iter(self): - # Add some vertices - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 0, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0))) - - # Add two faces - self.mesh.add_face(self.vhandle[2], self.vhandle[1], self.vhandle[0]) - self.mesh.add_face(self.vhandle[2], self.vhandle[0], self.vhandle[3]) - - # Test setup: - # 1 === 2 - # | / | - # | / | - # | / | - # 0 === 3 - - e_it = self.mesh.edges() - - e = e_it.__next__() - self.assertEqual(e.idx(), 0) - - he = self.mesh.halfedge_handle(e, 0) - self.assertEqual(self.mesh.to_vertex_handle(he).idx(), 1) - self.assertEqual(self.mesh.from_vertex_handle(he).idx(), 2) - he = self.mesh.halfedge_handle(e, 1) - self.assertEqual(self.mesh.to_vertex_handle(he).idx(), 2) - self.assertEqual(self.mesh.from_vertex_handle(he).idx(), 1) - - e = e_it.__next__() - self.assertEqual(e.idx(), 1) - - he = self.mesh.halfedge_handle(e, 0) - self.assertEqual(self.mesh.to_vertex_handle(he).idx(), 0) - self.assertEqual(self.mesh.from_vertex_handle(he).idx(), 1) - he = self.mesh.halfedge_handle(e, 1) - self.assertEqual(self.mesh.to_vertex_handle(he).idx(), 1) - self.assertEqual(self.mesh.from_vertex_handle(he).idx(), 0) - - e = e_it.__next__() - self.assertEqual(e.idx(), 2) - - he = self.mesh.halfedge_handle(e, 0) - self.assertEqual(self.mesh.to_vertex_handle(he).idx(), 2) - self.assertEqual(self.mesh.from_vertex_handle(he).idx(), 0) - he = self.mesh.halfedge_handle(e, 1) - self.assertEqual(self.mesh.to_vertex_handle(he).idx(), 0) - self.assertEqual(self.mesh.from_vertex_handle(he).idx(), 2) - - e = e_it.__next__() - self.assertEqual(e.idx(), 3) - - he = self.mesh.halfedge_handle(e, 0) - self.assertEqual(self.mesh.to_vertex_handle(he).idx(), 3) - self.assertEqual(self.mesh.from_vertex_handle(he).idx(), 0) - he = self.mesh.halfedge_handle(e, 1) - self.assertEqual(self.mesh.to_vertex_handle(he).idx(), 0) - self.assertEqual(self.mesh.from_vertex_handle(he).idx(), 3) - - e = e_it.__next__() - self.assertEqual(e.idx(), 4) - - he = self.mesh.halfedge_handle(e, 0) - self.assertEqual(self.mesh.to_vertex_handle(he).idx(), 2) - self.assertEqual(self.mesh.from_vertex_handle(he).idx(), 3) - he = self.mesh.halfedge_handle(e, 1) - self.assertEqual(self.mesh.to_vertex_handle(he).idx(), 3) - self.assertEqual(self.mesh.from_vertex_handle(he).idx(), 2) - - def test_halfedge_iter_skipping(self): - # Add some vertices - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, -1, 1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, -1, 1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, 1, 1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, 1, 1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, -1, -1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, -1, -1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, 1, -1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, 1, -1))) - - # Add six faces to form a cube - self.mesh.add_face(self.vhandle[0], self.vhandle[1], self.vhandle[3]) - self.mesh.add_face(self.vhandle[1], self.vhandle[2], self.vhandle[3]) - self.mesh.add_face(self.vhandle[7], self.vhandle[6], self.vhandle[5]) - self.mesh.add_face(self.vhandle[7], self.vhandle[5], self.vhandle[4]) - self.mesh.add_face(self.vhandle[1], self.vhandle[0], self.vhandle[4]) - self.mesh.add_face(self.vhandle[1], self.vhandle[4], self.vhandle[5]) - self.mesh.add_face(self.vhandle[2], self.vhandle[1], self.vhandle[5]) - self.mesh.add_face(self.vhandle[2], self.vhandle[5], self.vhandle[6]) - self.mesh.add_face(self.vhandle[3], self.vhandle[2], self.vhandle[6]) - self.mesh.add_face(self.vhandle[3], self.vhandle[6], self.vhandle[7]) - self.mesh.add_face(self.vhandle[0], self.vhandle[3], self.vhandle[7]) - self.mesh.add_face(self.vhandle[0], self.vhandle[7], self.vhandle[4]) - - # Test setup: - # - # 3 ======== 2 - # / /| - # / / | z - # 0 ======== 1 | | - # | | | | y - # | 7 | 6 | / - # | | / | / - # | |/ |/ - # 4 ======== 5 -------> x - - # Check setup - self.assertEqual(self.mesh.n_edges(), 18) - self.assertEqual(self.mesh.n_halfedges(), 36) - self.assertEqual(self.mesh.n_vertices(), 8) - self.assertEqual(self.mesh.n_faces(), 12) - - # Run over all halfedges - heCounter = 0 - - self.mesh.request_face_status() - self.mesh.request_vertex_status() - self.mesh.request_halfedge_status() - - # Get second edge - eh = self.mesh.edge_handle(2) - - # Delete one edge - self.mesh.delete_edge(eh) - - # Check setup ( No garbage collection, so nothing should change!) - self.assertEqual(self.mesh.n_edges(), 18) - self.assertEqual(self.mesh.n_halfedges(), 36) - self.assertEqual(self.mesh.n_vertices(), 8) - self.assertEqual(self.mesh.n_faces(), 12) - - # ===================================================== - # Check skipping iterator - # ===================================================== - - ok_4 = True - ok_5 = True - - count = 0 - - for he in self.mesh.shalfedges(): - if he.idx() == 4: - ok_4 = False - if he.idx() == 5: - ok_5 = False - count += 1 - - self.assertEqual(count, 34) - self.assertTrue(ok_4) - self.assertTrue(ok_5) - - # ===================================================== - # Check non skipping iterator - # ===================================================== - - ok_4 = False - ok_5 = False - - count = 0 - - for he in self.mesh.halfedges(): - if he.idx() == 4: - ok_4 = True - if he.idx() == 5: - ok_5 = True - count += 1 - - self.assertEqual(count, 36) - self.assertTrue(ok_4) - self.assertTrue(ok_5) - - def test_halfedge_iter_skipping_low_level(self): - # Add some vertices - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, -1, 1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, -1, 1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, 1, 1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, 1, 1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, -1, -1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, -1, -1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, 1, -1))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, 1, -1))) - - # Add six faces to form a cube - self.mesh.add_face(self.vhandle[0], self.vhandle[1], self.vhandle[3]) - self.mesh.add_face(self.vhandle[1], self.vhandle[2], self.vhandle[3]) - self.mesh.add_face(self.vhandle[7], self.vhandle[6], self.vhandle[5]) - self.mesh.add_face(self.vhandle[7], self.vhandle[5], self.vhandle[4]) - self.mesh.add_face(self.vhandle[1], self.vhandle[0], self.vhandle[4]) - self.mesh.add_face(self.vhandle[1], self.vhandle[4], self.vhandle[5]) - self.mesh.add_face(self.vhandle[2], self.vhandle[1], self.vhandle[5]) - self.mesh.add_face(self.vhandle[2], self.vhandle[5], self.vhandle[6]) - self.mesh.add_face(self.vhandle[3], self.vhandle[2], self.vhandle[6]) - self.mesh.add_face(self.vhandle[3], self.vhandle[6], self.vhandle[7]) - self.mesh.add_face(self.vhandle[0], self.vhandle[3], self.vhandle[7]) - self.mesh.add_face(self.vhandle[0], self.vhandle[7], self.vhandle[4]) - - # Test setup: - # - # 3 ======== 2 - # / /| - # / / | z - # 0 ======== 1 | | - # | | | | y - # | 7 | 6 | / - # | | / | / - # | |/ |/ - # 4 ======== 5 -------> x - - # Check setup - self.assertEqual(self.mesh.n_edges(), 18) - self.assertEqual(self.mesh.n_halfedges(), 36) - self.assertEqual(self.mesh.n_vertices(), 8) - self.assertEqual(self.mesh.n_faces(), 12) - - # Run over all halfedges - heCounter = 0 - - self.mesh.request_face_status() - self.mesh.request_vertex_status() - self.mesh.request_halfedge_status() - - # Get second edge - eh = self.mesh.edge_handle(2) - - # Delete one edge - self.mesh.delete_edge(eh) - - # Check setup ( No garbage collection, so nothing should change!) - self.assertEqual(self.mesh.n_edges(), 18) - self.assertEqual(self.mesh.n_halfedges(), 36) - self.assertEqual(self.mesh.n_vertices(), 8) - self.assertEqual(self.mesh.n_faces(), 12) - - # ===================================================== - # Try to add low level edge with invalid incidents and - # check skipping iterator - # ===================================================== - - # Add a low level edge without handles - eh_test = self.mesh.edge_handle(self.mesh.new_edge(openmesh.VertexHandle(), openmesh.VertexHandle())) - - count = 0 - found_4 = False - found_5 = False - found_36 = False - found_37 = False - - for he in self.mesh.shalfedges(): - if he.idx() == 4: - found_4 = True - if he.idx() == 5: - found_5 = True - if he.idx() == 36: - found_36 = True - if he.idx() == 37: - found_37 = True - count += 1 - - self.assertEqual(count, 36) - self.assertFalse(found_4) - self.assertFalse(found_5) - self.assertTrue(found_36) - self.assertTrue(found_37) - - # ===================================================== - # Try to delete one edge with invalid incidents and - # check skipping iterator - # ===================================================== - - # Delete one edge and recheck (Halfedges 4 and 5) - self.mesh.delete_edge(eh_test) - - count = 0 - found_4 = False - found_5 = False - found_36 = False - found_37 = False - - for he in self.mesh.shalfedges(): - if he.idx() == 4: - found_4 = True - if he.idx() == 5: - found_5 = True - if he.idx() == 36: - found_36 = True - if he.idx() == 37: - found_37 = True - count += 1 - - self.assertEqual(count, 34) - self.assertFalse(found_4) - self.assertFalse(found_5) - self.assertFalse(found_36) - self.assertFalse(found_37) - - def test_face_iter_empty_mesh_one_deleted_face(self): - # Request delete_face capability - self.mesh.request_vertex_status() - self.mesh.request_edge_status() - self.mesh.request_face_status() - - # Add some vertices - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 0, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 1, 0))) - - # Add one face - fh = self.mesh.add_face(self.vhandle[2], self.vhandle[1], self.vhandle[0]) - - is_delete_isolated_vertex = False - self.mesh.delete_face(fh, is_delete_isolated_vertex) - - # Test setup: - # 1 === 2 - # | / - # | / - # | / - # 0 - - # Normal iterators - f_it = self.mesh.faces() - - self.assertEqual(f_it.__next__().idx(), 0) - self.assertRaises(StopIteration, f_it.__next__) - - # Same with skipping iterators - f_it = self.mesh.sfaces() - - self.assertRaises(StopIteration, f_it.__next__) - - -if __name__ == '__main__': - suite = unittest.TestLoader().loadTestsFromTestCase(TriMeshIterators) - unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/src/Python/Unittests/test_trimesh_normal_calculations.py b/src/Python/Unittests/test_trimesh_normal_calculations.py deleted file mode 100644 index 68c8a7dc..00000000 --- a/src/Python/Unittests/test_trimesh_normal_calculations.py +++ /dev/null @@ -1,103 +0,0 @@ -import unittest -import openmesh - -class Normals(unittest.TestCase): - - def setUp(self): - self.mesh = openmesh.TriMesh() - - # Add some vertices - self.vhandle = [] - - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 0, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 0, 1))) - - # Add four faces - face_vhandles = [] - - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[2]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[3]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[3]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - - face_vhandles.append(self.vhandle[3]) - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[0]) - self.mesh.add_face(face_vhandles) - - def test_normal_calculations(self): - # Check one Request only vertex normals - # Face normals are required for vertex and halfedge normals, so - # that prevent access to non existing properties are in place - - self.mesh.request_vertex_normals() - self.mesh.request_halfedge_normals() - - # Check blocks - self.mesh.update_normals() - - # Request required face normals - self.mesh.request_face_normals() - - # Automatically compute all normals - # As only vertex normals are requested and no face normals, this will compute nothing. - self.mesh.update_normals() - - # Face normals alone - self.mesh.update_face_normals() - - # Vertex normals alone (require valid face normals) - self.mesh.update_vertex_normals() - - # Halfedge normals alone (require valid face normals) - self.mesh.update_halfedge_normals() - - def test_calc_vertex_normal_fast(self): - self.mesh.request_vertex_normals() - self.mesh.request_halfedge_normals() - self.mesh.request_face_normals() - - normal = openmesh.Vec3d() - - self.mesh.calc_vertex_normal_fast(self.vhandle[2], normal) - - def test_calc_vertex_normal_correct(self): - self.mesh.request_vertex_normals() - self.mesh.request_halfedge_normals() - self.mesh.request_face_normals() - - normal = openmesh.Vec3d() - - self.mesh.calc_vertex_normal_correct(self.vhandle[2], normal) - - def test_calc_vertex_normal_loop(self): - self.mesh.request_vertex_normals() - self.mesh.request_halfedge_normals() - self.mesh.request_face_normals() - - normal = openmesh.Vec3d() - - self.mesh.calc_vertex_normal_loop(self.vhandle[2], normal) - - -if __name__ == '__main__': - suite = unittest.TestLoader().loadTestsFromTestCase(Normals) - unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/src/Python/Unittests/test_trimesh_others.py b/src/Python/Unittests/test_trimesh_others.py deleted file mode 100644 index bd559195..00000000 --- a/src/Python/Unittests/test_trimesh_others.py +++ /dev/null @@ -1,129 +0,0 @@ -import unittest -import openmesh - -from math import pi, fabs - -class Others(unittest.TestCase): - - def setUp(self): - self.mesh = openmesh.TriMesh() - self.vhandle = [] - - def test_is_estimated_feature_edge(self): - # Add some vertices - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 0, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 0, 1))) - - # Add four faces - face_vhandles = [] - - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[2]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[3]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[3]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - - face_vhandles.append(self.vhandle[3]) - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[0]) - self.mesh.add_face(face_vhandles) - - # =============================================== - # Setup complete - # =============================================== - - - # Check one Request only vertex normals - # Face normals are required for vertex and halfedge normals, so - # that prevent access to non existing properties are in place - - self.mesh.request_vertex_normals() - self.mesh.request_halfedge_normals() - self.mesh.request_face_normals() - - # Automatically compute all normals - # As only vertex normals are requested and no face normals, this will compute nothing. - self.mesh.update_normals() - - he = self.mesh.halfedges().__next__() - - self.assertTrue(self.mesh.is_estimated_feature_edge(he, 0.0)) - self.assertTrue(self.mesh.is_estimated_feature_edge(he, 0.125 * pi)) - self.assertTrue(self.mesh.is_estimated_feature_edge(he, 0.250 * pi)) - self.assertTrue(self.mesh.is_estimated_feature_edge(he, 0.375 * pi)) - self.assertTrue(self.mesh.is_estimated_feature_edge(he, 0.500 * pi)) - self.assertFalse(self.mesh.is_estimated_feature_edge(he, 0.625 * pi)) - self.assertFalse(self.mesh.is_estimated_feature_edge(he, 0.750 * pi)) - self.assertFalse(self.mesh.is_estimated_feature_edge(he, 0.875 * pi)) - self.assertFalse(self.mesh.is_estimated_feature_edge(he, 1.000 * pi)) - - def test_is_estimated_feature_edge(self): - # Test setup: - # 1 -- 2 - # | / | - # | / | - # 0 -- 3 - - # Add some vertices - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 0, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 1, 0))) - self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0))) - - # Add two faces - face_vhandles = [] - - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[1]) - face_vhandles.append(self.vhandle[2]) - self.mesh.add_face(face_vhandles) - - face_vhandles = [] - - face_vhandles.append(self.vhandle[0]) - face_vhandles.append(self.vhandle[2]) - face_vhandles.append(self.vhandle[3]) - self.mesh.add_face(face_vhandles) - - # =============================================== - # Setup complete - # =============================================== - - he = self.mesh.halfedge_handle(4) - - self.assertEqual(self.mesh.to_vertex_handle(he).idx(), 0) - self.assertEqual(self.mesh.from_vertex_handle(he).idx(), 2) - self.assertEqual(self.mesh.edge_handle(he).idx(), 2) - - eh = self.mesh.edge_handle(he) - self.assertEqual(self.mesh.calc_dihedral_angle(eh), 0.0) - - # Modify point - tmp = (openmesh.Vec3d(0.0, 0.0, -1.0) + openmesh.Vec3d(1.0, 1.0, -1.0)) * 0.5 - self.mesh.set_point(self.vhandle[2], tmp) - - difference = fabs(1.36944 - self.mesh.calc_dihedral_angle(eh)) - - self.assertTrue(difference < 0.00001) - - -if __name__ == '__main__': - suite = unittest.TestLoader().loadTestsFromTestCase(Others) - unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/src/Python/Unittests/test_vector_type.py b/src/Python/Unittests/test_vector_type.py deleted file mode 100644 index 795d3fef..00000000 --- a/src/Python/Unittests/test_vector_type.py +++ /dev/null @@ -1,46 +0,0 @@ -import unittest -import openmesh - -class VectorTest(unittest.TestCase): - - def test_compute_triangle_surface_with_cross_product(self): - # vec1 - # y - # | - # | - # | - # x------>x vec2 - - vec1 = openmesh.Vec3d(0.0, 1.0, 0.0) - vec2 = openmesh.Vec3d(1.0, 0.0, 0.0) - - area = 0.5 * openmesh.cross(vec1, vec2).norm() - self.assertEqual(area, 0.5) - - area = 0.5 * (vec1 % vec2).norm() - self.assertEqual(area, 0.5) - - def test_equality_operator_vec3d(self): - vec1 = openmesh.Vec3d(0.0, 1.0, 0.0) - vec2 = openmesh.Vec3d(1.0, 0.0, 0.0) - vec3 = openmesh.Vec3d(1.0, 0.0, 0.0) - - self.assertFalse(vec1==vec2) - self.assertTrue(vec3==vec2) - - def test_equality_operator_vec3f(self): - vec1 = openmesh.Vec3f(0.0, 1.0, 0.0) - vec2 = openmesh.Vec3f(1.0, 0.0, 0.0) - vec3 = openmesh.Vec3f(1.0, 0.0, 0.0) - - self.assertFalse(vec1==vec2) - self.assertTrue(vec3==vec2) - - def test_abs_test(self): - vec1 = openmesh.Vec3d(0.5, 0.5, -0.5) - self.assertEqual(vec1.l8_norm(), 0.5) - - -if __name__ == '__main__': - suite = unittest.TestLoader().loadTestsFromTestCase(VectorTest) - unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/src/Python/Vector.hh b/src/Python/Vector.hh deleted file mode 100644 index 1aa38519..00000000 --- a/src/Python/Vector.hh +++ /dev/null @@ -1,193 +0,0 @@ -#ifndef OPENMESH_PYTHON_VECTOR_HH -#define OPENMESH_PYTHON_VECTOR_HH - -#include "Python/Bindings.hh" - -namespace OpenMesh { -namespace Python { - -template -void set_item(Vector& _vec, int _index, Scalar _value) { - if (_index < 0) { - _index += _vec.size(); - } - - if ((size_t)_index < _vec.size()) { - _vec[_index] = _value; - } - else { - PyErr_SetString(PyExc_IndexError, "Index out of range."); - throw_error_already_set(); - } -} - -template -Scalar get_item(Vector& _vec, int _index) { - if (_index < 0) { - _index += _vec.size(); - } - - if ((size_t)_index < _vec.size()) { - return _vec[_index]; - } - else { - PyErr_SetString(PyExc_IndexError, "Index out of range."); - throw_error_already_set(); - } - - return 0.0; -} - -namespace { -template -struct Factory { - typedef OpenMesh::VectorT Vector2; - typedef OpenMesh::VectorT Vector3; - typedef OpenMesh::VectorT Vector4; - - static Vector2 *vec2_default() { - return new Vector2(Scalar(), Scalar()); - } - static Vector2 *vec2_user_defined(const Scalar& _v0, const Scalar& _v1) { - return new Vector2(_v0, _v1); - } - static Vector3 *vec3_default() { - return new Vector3(Scalar(), Scalar(), Scalar()); - } - static Vector3 *vec3_user_defined(const Scalar& _v0, const Scalar& _v1, const Scalar& _v2) { - return new Vector3(_v0, _v1, _v2); - } - static Vector4 *vec4_default() { - return new Vector4(Scalar(), Scalar(), Scalar(), Scalar()); - } - static Vector4 *vec4_user_defined(const Scalar& _v0, const Scalar& _v1, const Scalar& _v2, const Scalar& _v3) { - return new Vector4(_v0, _v1, _v2, _v3); - } -}; -} - -template -void defInitMod(class_< OpenMesh::VectorT > &classVector) { - classVector - .def("__init__", make_constructor(&Factory::vec2_default)) - .def("__init__", make_constructor(&Factory::vec2_user_defined)) - ; -} - -template -void defInitMod(class_< OpenMesh::VectorT > &classVector) { - Vector (Vector::*cross)(const Vector&) const = &Vector::operator%; - classVector - .def("__init__", make_constructor(&Factory::vec3_default)) - .def("__init__", make_constructor(&Factory::vec3_user_defined)) - .def("__mod__", cross) - ; - def("cross", cross); -} - -template -void defInitMod(class_< OpenMesh::VectorT > &classVector) { - classVector - .def("__init__", make_constructor(&Factory::vec4_default)) - .def("__init__", make_constructor(&Factory::vec4_user_defined)) - ; -} - -/** - * Expose a vector type to %Python. - * - * This function template is used to expose vectors to %Python. The template - * parameters are used to instantiate the appropriate vector type. - * - * @tparam Scalar A scalar type. - * @tparam N The dimension of the vector. - * - * @param _name The name of the vector type to be exposed. - * - * @note N must be either 2, 3 or 4. - */ -template -void expose_vec(const char *_name) { - typedef OpenMesh::VectorT Vector; - - Scalar (Vector::*min_void)() const = &Vector::min; - Scalar (Vector::*max_void)() const = &Vector::max; - - Vector (Vector::*max_vector)(const Vector&) const = &Vector::max; - Vector (Vector::*min_vector)(const Vector&) const = &Vector::min; - - Scalar (Vector::*dot )(const Vector&) const = &Vector::operator|; - Scalar (Vector::*norm )(void ) const = &Vector::norm; - Scalar (Vector::*length )(void ) const = &Vector::length; - Scalar (Vector::*sqrnorm )(void ) const = &Vector::sqrnorm; - Vector& (Vector::*normalize )(void ) = &Vector::normalize; - Vector& (Vector::*normalize_cond)(void ) = &Vector::normalize_cond; - -#if (_MSC_VER >= 1800 || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)) && !defined(OPENMESH_VECTOR_LEGACY) - Vector (Vector::*normalized)() const = &Vector::normalized; -#else - const Vector (Vector::*normalized)() const = &Vector::normalized; -#endif - - class_ classVector = class_(_name); - - classVector - .def("__setitem__", &set_item) - .def("__getitem__", &get_item) - .def(self == self) - .def(self != self) - .def(self *= Scalar()) - .def(self /= Scalar()) - .def(self * Scalar()) - .def(Scalar() * self) - .def(self / Scalar()) - .def(self *= self) - .def(self /= self) - .def(self -= self) - .def(self += self) - .def(self * self) - .def(self / self) - .def(self + self) - .def(self - self) - .def(-self) - .def(self | self) - .def("vectorize", &Vector::vectorize, return_internal_reference<>()) - .def(self < self) - - .def("dot", dot) - .def("norm", norm) - .def("length", length) - .def("sqrnorm", sqrnorm) - .def("normalized", normalized) - .def("normalize", normalize, return_internal_reference<>()) - .def("normalize_cond", normalize_cond, return_internal_reference<>()) - - .def("l1_norm", &Vector::l1_norm) - .def("l8_norm", &Vector::l8_norm) - - .def("max", max_void) - .def("max_abs", &Vector::max_abs) - .def("min", min_void) - .def("min_abs", &Vector::min_abs) - .def("mean", &Vector::mean) - .def("mean_abs", &Vector::mean_abs) - .def("minimize", &Vector::minimize, return_internal_reference<>()) - .def("minimized", &Vector::minimized) - .def("maximize", &Vector::maximize, return_internal_reference<>()) - .def("maximized", &Vector::maximized) - .def("min", min_vector) - .def("max", max_vector) - - .def("size", &Vector::size) - .staticmethod("size") - .def("vectorized", &Vector::vectorized) - .staticmethod("vectorized") - ; - - defInitMod(classVector); -} - -} // namespace OpenMesh -} // namespace Python - -#endif \ No newline at end of file diff --git a/src/Unittests/CMakeLists.txt b/src/Unittests/CMakeLists.txt index a6ea5e7b..e11060cf 100644 --- a/src/Unittests/CMakeLists.txt +++ b/src/Unittests/CMakeLists.txt @@ -11,41 +11,63 @@ endif() if ( OPENMESH_BUILD_UNIT_TESTS ) # Search for gtest headers and libraries - find_package(GoogleTest) + find_package(GTest) if(GTEST_FOUND) enable_testing() + find_package(EIGEN3) + # Set correct include paths so that the compiler can find the headers - include_directories(${GTEST_INCLUDE_DIRS}) + include_directories(${GTEST_INCLUDE_DIRS} ) + + # set additional link directories link_directories(${GTEST_LIBRARY_DIR} ) + + if (EIGEN3_FOUND) + add_definitions( -DENABLE_EIGEN3_TEST ) + include_directories(${EIGEN3_INCLUDE_DIR}) + endif() + if ( CMAKE_GENERATOR MATCHES "^Visual Studio 11.*" ) add_definitions( /D _VARIADIC_MAX=10 ) endif() # Create new target named unittests_hexmeshing FILE(GLOB UNITTEST_SRC *.cc) - # Create unittest executable - acg_add_executable(unittests ${UNITTEST_SRC}) + # Create unittest executable + acg_add_executable(unittests ${UNITTEST_SRC}) + acg_add_executable(unittests_customvec ${UNITTEST_SRC}) + acg_add_executable(unittests_doublevec ${UNITTEST_SRC}) + target_compile_definitions(unittests_customvec PRIVATE TEST_CUSTOM_TRAITS) + target_compile_definitions(unittests_doublevec PRIVATE TEST_DOUBLE_TRAITS) - # For the unittest we don't want the install rpath as set by acg_add_executable - set_target_properties ( unittests PROPERTIES BUILD_WITH_INSTALL_RPATH 0 ) + # For the unittest we don't want the install rpath as set by acg_add_executable + set_target_properties ( unittests PROPERTIES BUILD_WITH_INSTALL_RPATH 0 ) + set_target_properties ( unittests_customvec PROPERTIES BUILD_WITH_INSTALL_RPATH 0 ) + set_target_properties ( unittests_doublevec PROPERTIES BUILD_WITH_INSTALL_RPATH 0 ) # Set output directory to ${BINARY_DIR}/Unittests set (OUTPUT_DIR "${CMAKE_BINARY_DIR}/Unittests") - set_target_properties(unittests PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${OUTPUT_DIR}) + set_target_properties(unittests PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${OUTPUT_DIR}) + set_target_properties(unittests_customvec PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${OUTPUT_DIR}) + set_target_properties(unittests_doublevec PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${OUTPUT_DIR}) foreach(CONFIG ${CMAKE_CONFIGURATION_TYPES}) string(TOUPPER ${CONFIG} UPCONFIG) set_target_properties(unittests PROPERTIES RUNTIME_OUTPUT_DIRECTORY_${UPCONFIG} ${OUTPUT_DIR}) + set_target_properties(unittests_customvec PROPERTIES RUNTIME_OUTPUT_DIRECTORY_${UPCONFIG} ${OUTPUT_DIR}) + set_target_properties(unittests_doublevec PROPERTIES RUNTIME_OUTPUT_DIRECTORY_${UPCONFIG} ${OUTPUT_DIR}) endforeach() if ( NOT WIN32) # Link against all necessary libraries target_link_libraries(unittests OpenMeshCore OpenMeshTools ${GTEST_LIBRARIES} ${GTEST_MAIN_LIBRARIES} pthread) + target_link_libraries(unittests_customvec OpenMeshCore OpenMeshTools ${GTEST_LIBRARIES} ${GTEST_MAIN_LIBRARIES} pthread) + target_link_libraries(unittests_doublevec OpenMeshCore OpenMeshTools ${GTEST_LIBRARIES} ${GTEST_MAIN_LIBRARIES} pthread) @@ -55,7 +77,9 @@ if ( OPENMESH_BUILD_UNIT_TESTS ) add_definitions( -DOPENMESHDLL ) endif() - target_link_libraries(unittests OpenMeshCore OpenMeshTools ${GTEST_LIBRARIES} ${GTEST_MAIN_LIBRARIES}) + target_link_libraries(unittests OpenMeshCore OpenMeshTools ${GTEST_LIBRARIES} ${GTEST_MAIN_LIBRARIES}) + target_link_libraries(unittests_customvec OpenMeshCore OpenMeshTools ${GTEST_LIBRARIES} ${GTEST_MAIN_LIBRARIES}) + target_link_libraries(unittests_doublevec OpenMeshCore OpenMeshTools ${GTEST_LIBRARIES} ${GTEST_MAIN_LIBRARIES}) endif() @@ -63,10 +87,13 @@ if ( OPENMESH_BUILD_UNIT_TESTS ) if ( NOT WIN32 ) # Set compiler flags set_target_properties(unittests PROPERTIES COMPILE_FLAGS "-g -pedantic -Wno-long-long") + set_target_properties(unittests_customvec PROPERTIES COMPILE_FLAGS "-g -pedantic -Wno-long-long") + set_target_properties(unittests_doublevec PROPERTIES COMPILE_FLAGS "-g -pedantic -Wno-long-long") else() # Set compiler flags set_target_properties(unittests PROPERTIES COMPILE_FLAGS "" ) - + set_target_properties(unittests_customvec PROPERTIES COMPILE_FLAGS "" ) + set_target_properties(unittests_doublevec PROPERTIES COMPILE_FLAGS "" ) endif() if ( OPENMESH_BUILD_SHARED ) @@ -80,12 +107,26 @@ if ( OPENMESH_BUILD_UNIT_TESTS ) "$" "${CMAKE_BINARY_DIR}/Unittests/$" COMMENT "Copying OpenMesh targets to unittests directory") + add_custom_command(TARGET unittests_customvec POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E copy + "$" + "${CMAKE_BINARY_DIR}/Unittests/$" + COMMENT "Copying OpenMesh targets to unittests directory") + add_custom_command(TARGET unittests_doublevec POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E copy + "$" + "${CMAKE_BINARY_DIR}/Unittests/$" + COMMENT "Copying OpenMesh targets to unittests directory") endforeach(TAR) endif() acg_copy_after_build(unittests ${CMAKE_CURRENT_SOURCE_DIR}/TestFiles ${CMAKE_BINARY_DIR}/Unittests/) + acg_copy_after_build(unittests_customvec ${CMAKE_CURRENT_SOURCE_DIR}/TestFiles ${CMAKE_BINARY_DIR}/Unittests/) + acg_copy_after_build(unittests_doublevec ${CMAKE_CURRENT_SOURCE_DIR}/TestFiles ${CMAKE_BINARY_DIR}/Unittests/) add_test(NAME AllTestsIn_OpenMesh_tests WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/Unittests" COMMAND "${CMAKE_BINARY_DIR}/Unittests/unittests") + add_test(NAME AllTestsIn_OpenMesh_tests_with_minimal_vector WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/Unittests" COMMAND "${CMAKE_BINARY_DIR}/Unittests/unittests_customvec") + add_test(NAME AllTestsIn_OpenMesh_tests_with_double_vector WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/Unittests" COMMAND "${CMAKE_BINARY_DIR}/Unittests/unittests_doublevec") else(GTEST_FOUND) message(STATUS "Google testing framework was not found, unittests disabled.") diff --git a/src/Unittests/TestFiles/cube-minimal-custom_props-binary.ply b/src/Unittests/TestFiles/cube-minimal-custom_props-binary.ply new file mode 100644 index 00000000..53be426b Binary files /dev/null and b/src/Unittests/TestFiles/cube-minimal-custom_props-binary.ply differ diff --git a/src/Unittests/TestFiles/cube-minimal-faceColors.ply b/src/Unittests/TestFiles/cube-minimal-faceColors.ply new file mode 100644 index 00000000..4b97743e --- /dev/null +++ b/src/Unittests/TestFiles/cube-minimal-faceColors.ply @@ -0,0 +1,33 @@ +ply +format ascii 1.0 +comment VCGLIB generated +element vertex 8 +property float x +property float y +property float z +element face 12 +property list uchar int vertex_indices +property float red +property float green +property float blue +end_header +-1 -1 -1 +1 -1 -1 +1 1 -1 +-1 1 -1 +-1 -1 1 +1 -1 1 +1 1 1 +-1 1 1 +3 0 1 2 0.419608 0.462745 0.698039 +3 0 2 3 1.0 0.552941 0.419608 +3 5 4 7 0.698039 1.0 0.619608 +3 5 7 6 0.419608 1.0 0.529412 +3 6 2 1 0.643137 0.419608 0.698039 +3 6 1 5 0.643137 0.419608 1.0 +3 3 7 4 0.698039 0.552941 1.0 +3 3 4 0 1.0 0.552941 0.419608 +3 7 3 2 0.419608 0.698039 1.0 +3 7 2 6 0.419608 0.698039 0.529412 +3 5 1 0 1.0 0.419608 1.0 +3 5 0 4 0.698039 1.0 1.0 diff --git a/src/Unittests/TestFiles/cube_noisy.off b/src/Unittests/TestFiles/cube_noisy.off new file mode 100644 index 00000000..682f4545 --- /dev/null +++ b/src/Unittests/TestFiles/cube_noisy.off @@ -0,0 +1,22576 @@ +OFF +7526 15048 22572 +0.514241 0.260794 0.389481 +0.297698 0.497249 0.10116 +0.360255 -0.0847248 0.510251 +0.391241 -0.505697 -0.0913271 +0.391198 -0.513677 -0.189891 +0.350372 0.185531 -0.502437 +-0.30363 -0.241076 -0.499723 +-0.0878174 -0.469778 0.479027 +0.506531 0.314524 -0.315277 +-0.038812 0.491603 0.0330997 +0.196215 0.497778 -0.362234 +0.502636 0.344526 0.172434 +-0.0145036 0.493906 0.0119593 +0.492366 0.116239 -0.236048 +0.133863 0.326282 -0.495219 +-0.501158 -0.228021 -0.383876 +-0.0038548 0.495309 -0.0431288 +-0.511951 -0.287301 0.30909 +-0.11319 -0.473118 0.474236 +-0.376441 -0.498093 0.220531 +0.508925 -0.32517 0.352425 +0.419334 0.0522122 0.500184 +-0.513258 -0.132065 0.388807 +0.506051 0.354572 -0.354276 +0.508415 -0.28378 0.194456 +-0.129719 -0.50238 0.0674791 +-0.509423 0.101175 0.299977 +0.356571 0.496521 -0.0626822 +-0.122238 0.507579 -0.353068 +-0.28295 0.509952 0.403822 +-0.299738 0.511306 0.427376 +0.257826 0.498698 -0.433102 +-0.361595 0.0561925 -0.513503 +-0.374514 -0.255346 -0.510803 +-0.497072 -0.384364 -0.291127 +-0.353911 -0.0543684 -0.511565 +-0.356338 0.220465 -0.498435 +0.491735 0.239681 0.430717 +0.501453 -0.362293 -0.198343 +0.407611 -0.0375049 -0.501424 +0.323903 0.0544111 -0.500885 +-0.50282 0.076916 -0.354627 +0.241551 0.375286 -0.512576 +0.0784178 0.431071 -0.498371 +0.186606 -0.312144 -0.504114 +0.00462675 0.513463 -0.366767 +-0.290036 -0.507806 -0.1207 +0.198986 -0.391277 -0.510329 +0.262313 0.510329 -0.364633 +0.498214 0.23671 0.385754 +0.121234 0.513462 -0.372622 +0.496523 0.279743 0.40296 +-0.167006 0.506901 0.401652 +-0.466733 -0.475328 0.466697 +-0.0692496 -0.498283 -0.41716 +0.150435 0.500147 0.280103 +0.0508637 0.499522 0.127757 +-0.085264 0.303739 -0.497287 +-0.0988902 0.333398 -0.503278 +0.157482 0.28578 -0.494304 +0.453319 0.494224 -0.177755 +-0.349115 -0.504338 0.225545 +0.452947 0.315872 0.492648 +-0.0792462 0.190701 -0.505158 +-0.0959438 0.390866 -0.496378 +0.350816 -0.508004 -0.0637243 +0.377276 -0.507975 -0.054571 +-0.350931 -0.211483 -0.498894 +-0.0394934 0.509301 0.413632 +0.347754 0.518156 -0.359102 +-0.107399 0.417825 0.503022 +0.304604 0.500476 0.263458 +0.163125 0.501441 0.340233 +0.365678 0.503464 0.132535 +0.395444 0.506761 -0.124356 +0.510745 0.397182 0.242204 +-0.39656 -0.47873 0.466738 +0.398499 -0.505877 0.362293 +-0.435175 -0.00644067 -0.497732 +0.510366 0.254923 -0.0698744 +-0.399483 -0.507949 0.349548 +-0.161345 0.498167 0.0552714 +-0.493908 0.412257 0.38658 +-0.49722 0.407777 -0.214376 +-0.498915 -0.285068 -0.0137039 +-0.368457 0.457726 0.488045 +0.29616 0.504235 0.0520809 +-0.509543 -0.305802 -0.422671 +-0.135075 0.457311 -0.491915 +0.491873 0.193846 0.404482 +-0.353373 -0.513171 0.139359 +0.396335 -0.337063 -0.508366 +0.45704 0.467045 0.469633 +-0.364006 -0.143038 -0.504277 +0.461892 -0.479914 -0.0583538 +-0.499518 -0.0152554 -0.429329 +-0.457629 0.467851 0.45455 +0.511935 0.0855908 -0.363309 +-0.015315 0.509135 -0.38202 +0.274379 0.51121 -0.0369229 +-0.107081 0.432794 -0.504824 +0.229172 0.49648 -0.0260922 +0.497739 0.369047 0.161022 +-0.400655 -0.0308557 -0.494597 +-0.503203 0.289622 -0.441392 +-0.377279 0.512899 -0.221777 +0.470121 -0.46804 0.472684 +0.498561 -0.348059 0.402997 +-0.266104 0.502657 0.381322 +0.289553 0.343318 -0.507351 +0.509786 0.146771 0.217466 +0.0504273 0.50967 0.389199 +-0.463253 0.239748 0.494587 +-0.487842 0.381191 -0.476391 +0.490061 0.27197 0.426012 +-0.494082 0.266486 -0.429969 +-0.195843 -0.503327 0.381545 +-0.201337 0.506819 0.394578 +-0.0327119 0.508241 -0.0995204 +0.0324077 -0.218571 -0.510026 +-0.482844 -0.467995 -0.377071 +-0.508444 0.0166795 0.256253 +0.126977 -0.501281 0.280014 +0.165608 0.49663 -0.361152 +-0.313168 -0.504758 0.357503 +0.431967 0.476588 0.473703 +0.505845 0.336948 -0.131871 +0.229054 0.50225 0.261689 +-0.178973 -0.504289 0.303385 +-0.230636 0.495363 -0.0967162 +-0.492019 0.0853994 -0.441676 +0.480142 -0.461699 0.401477 +-0.244922 0.5023 0.101107 +-0.00701702 -0.504917 0.320227 +0.469649 -0.476417 -0.0122012 +0.412506 0.497022 0.114869 +-0.500873 0.328428 -0.0524091 +0.139367 -0.214692 0.495107 +-0.495922 0.416865 -0.143049 +0.0371125 -0.338751 0.506101 +0.194454 0.374311 0.509604 +0.113298 0.0350137 0.495803 +0.500824 0.26324 -0.243624 +-0.346562 0.508945 -0.233398 +0.188248 0.498248 -0.260824 +-0.0417355 0.500218 0.278718 +-0.241036 -0.511338 -0.373496 +-0.330028 0.508771 -0.0690599 +-0.518303 0.324865 0.39429 +-0.125245 -0.504931 -0.411078 +-0.211318 0.503123 0.0931688 +-0.122557 -0.501955 0.236217 +-0.0200276 0.504526 -0.327324 +-0.387127 -0.375608 -0.50007 +0.270515 -0.50508 0.212785 +0.386311 -0.513973 -0.307158 +-0.498964 -0.446609 -0.361398 +-0.262124 0.135083 -0.493979 +-0.466896 -0.442306 0.466455 +-0.161051 -0.501956 -0.353556 +-0.466893 0.200224 -0.482607 +-0.501638 -0.210806 0.129433 +-0.31468 0.462997 0.490164 +-0.493356 0.465367 0.33123 +-0.474615 -0.460055 -0.221128 +-0.513773 -0.382464 -0.0440984 +-0.494433 -0.20239 0.186703 +-0.498693 -0.231418 0.175863 +-0.447764 0.321207 -0.490603 +-0.504636 -0.394999 -0.227966 +0.354899 -0.514221 0.168281 +0.301647 -0.185196 0.512339 +0.430558 0.451463 -0.491663 +-0.100984 0.495744 -0.0537774 +-0.230184 -0.507027 0.341412 +0.388348 -0.239557 -0.49907 +-0.346785 -0.509935 -0.198814 +0.476835 0.464798 -0.140195 +0.513004 0.308586 0.396829 +-0.118841 0.502882 -0.0276163 +-0.332925 0.513439 0.108777 +-0.106253 0.503917 0.327791 +0.500055 -0.349158 -0.171099 +0.0789442 -0.49895 0.241247 +0.0490991 -0.50294 0.255846 +-0.405155 -0.509324 0.127255 +0.420114 -0.0557219 -0.493231 +0.497137 0.226218 -0.162139 +0.518693 0.352898 0.314199 +0.220748 -0.485572 -0.456282 +-0.506515 0.0165253 -0.301694 +0.472621 0.456981 -0.466823 +-0.212888 0.510211 0.0110635 +0.494218 0.136986 0.0570617 +0.501636 0.31085 -0.231084 +-0.284898 0.356745 0.498976 +0.410425 0.497925 0.246248 +-0.355998 0.508624 0.333746 +-0.222348 0.499632 -0.0707468 +0.0652895 0.499446 -0.0155165 +0.3171 -0.495725 0.0442607 +-0.0822301 -0.497587 0.166004 +0.437017 -0.139031 -0.492672 +-0.513914 -0.0553841 -0.371831 +-0.452134 0.379373 -0.496917 +0.00626206 -0.318247 0.513742 +0.497339 -0.344979 -0.219835 +-0.50159 0.0559668 -0.402565 +0.499543 0.373819 0.103436 +0.0826275 -0.511211 -0.292456 +0.089208 -0.496681 -0.32533 +0.112673 0.159834 0.491927 +-0.479738 0.244437 0.467206 +0.0949935 0.176378 0.496336 +0.431744 0.498961 0.229497 +0.0598788 0.230174 0.509295 +0.0673612 0.261452 0.495918 +-0.479914 -0.460424 -0.462345 +-0.504697 0.302984 0.340897 +-0.499504 -0.0487516 0.376941 +0.0700035 0.406206 -0.495078 +-0.509101 0.0863784 0.253126 +0.0606915 0.382991 -0.505412 +0.491209 0.324813 0.435275 +-0.499617 0.258841 -0.372674 +0.495999 0.457064 -0.382384 +-0.081462 0.496853 -0.287092 +-0.0861862 -0.502008 0.346596 +-0.502254 0.0631835 0.324595 +0.371467 -0.509348 -0.213548 +0.511703 0.132211 0.339846 +0.451661 -0.491146 -0.0693436 +0.157789 0.312873 -0.494776 +0.0736673 -0.336442 -0.500217 +-0.0378784 0.352628 0.50389 +-0.267467 -0.50768 -0.110802 +0.272216 -0.497099 0.0501377 +-0.0697181 0.499386 0.022345 +-0.0946568 -0.49532 0.241625 +-0.504941 0.233382 0.297161 +-0.503261 0.259113 0.274077 +-0.495784 0.0824493 0.0884287 +0.469158 0.479769 -0.15799 +-0.323199 -0.200564 -0.509644 +-0.11398 -0.505021 0.26444 +0.493451 0.237002 0.0649826 +0.502997 0.208257 0.0550538 +-0.513277 0.324195 0.207209 +0.515246 0.283247 0.377175 +0.510295 -0.0753759 0.27422 +0.280434 0.499346 -0.339738 +-0.366866 0.294715 0.49797 +0.320787 0.510145 -0.0615488 +-0.169803 -0.50282 0.252639 +-0.496228 -0.292572 -0.106396 +0.0368386 0.336069 0.514221 +0.231529 0.463254 0.479916 +0.382732 0.500888 0.105085 +-0.14028 0.495171 0.196575 +0.506498 0.0263179 -0.0972221 +-0.234732 0.153012 0.510126 +-0.243861 0.126585 0.493271 +0.0927315 0.495787 0.00809219 +-0.0234196 0.490734 0.0936242 +-0.506521 -0.344912 0.290645 +-0.22942 0.507132 0.268952 +-0.0158064 -0.511262 -0.391721 +0.0767868 -0.505508 0.272872 +0.00815185 -0.49927 0.367765 +-0.0664202 0.331186 -0.495671 +-0.114281 0.363778 -0.497399 +-0.203727 0.15766 0.500839 +0.497316 0.1673 -0.0807291 +0.504028 0.178014 -0.132856 +0.496168 0.216953 -0.108007 +-0.477651 -0.45815 0.161519 +-0.511473 -0.091903 0.396989 +0.452748 -0.499278 -0.12164 +-0.0234735 -0.332024 0.513044 +0.51083 -0.0461175 0.34869 +-0.511995 0.0741974 0.351071 +-0.385471 0.0668716 0.514089 +0.504972 -0.0801782 0.116594 +-0.510505 -0.342479 -0.25591 +-0.294025 0.504718 -0.146169 +-0.398087 -0.514353 0.276497 +-0.389752 -0.507745 0.247913 +-0.508069 0.422638 0.422565 +-0.494946 -0.207468 0.157802 +-0.486867 -0.370606 -0.479783 +0.0540012 0.442486 0.501032 +-0.497365 0.27503 -0.0493679 +-0.477882 0.0384307 -0.455996 +0.0764719 -0.0119528 0.492243 +0.467662 -0.452747 0.467938 +-0.0236265 -0.285965 -0.501629 +0.485114 0.285849 -0.476171 +0.146457 0.12941 0.49183 +0.358976 0.013615 -0.497407 +-0.491896 -0.127901 0.261154 +0.197234 -0.493827 -0.189921 +-0.343903 -0.216428 0.50056 +-0.0811629 -0.501583 0.220547 +-0.0528761 -0.332433 -0.506798 +-0.0141544 -0.347455 -0.514425 +-0.40615 0.383575 -0.510442 +-0.246561 0.309177 0.508892 +0.458367 0.475548 -0.470222 +-0.467281 -0.0762531 -0.486882 +-0.511412 0.351998 0.386629 +0.418732 -0.295312 -0.507231 +-0.503668 -0.188664 0.0837569 +0.0655347 0.0170776 0.5008 +-0.279661 -0.504345 -0.27661 +0.0437138 0.276469 -0.499336 +-0.32235 -0.261554 0.498939 +0.0216298 0.496526 0.0220569 +-0.443918 -0.503451 0.266519 +0.459024 -0.475915 0.0107994 +-0.318405 -0.444448 0.497414 +0.312276 0.150216 -0.511128 +-0.347948 -0.269409 0.515575 +0.00432694 -0.510311 0.399983 +0.23513 -0.507959 -0.118503 +-0.251936 -0.308846 -0.515832 +-0.0886175 0.496644 -0.318986 +-0.0408546 0.169192 0.496078 +-0.391471 0.426941 0.506355 +0.359577 0.154584 0.500361 +0.311862 0.0828694 -0.502285 +0.352505 0.0463455 -0.511612 +-0.309903 -0.12229 -0.5028 +-0.508887 -0.34842 0.211692 +-0.498438 0.209761 -0.220848 +-0.469972 0.457153 -0.43966 +0.274942 -0.485471 0.467 +-0.495065 0.206735 -0.198999 +-0.331275 0.260072 0.511344 +-0.177454 -0.480189 -0.467384 +-0.25056 0.341965 0.498221 +0.41707 -0.497078 0.013382 +-0.227862 0.428698 -0.490763 +-0.506772 -0.241597 0.0903982 +0.162367 -0.40394 0.509874 +0.158018 -0.50411 0.32288 +0.189979 -0.495645 0.280568 +0.158128 -0.511239 0.277289 +-0.189749 0.399378 -0.510041 +-0.177094 0.376841 -0.497328 +-0.209332 0.339801 -0.495947 +0.34715 -0.20424 0.502414 +0.314559 -0.245962 0.51463 +0.0263778 -0.151487 -0.507326 +0.457198 -0.479489 0.286666 +-0.239485 -0.50721 -0.101554 +0.264175 -0.509983 0.188075 +0.469221 -0.474137 0.347212 +-0.200431 -0.492748 -0.174615 +-0.29885 0.330374 -0.512406 +0.407125 -0.334544 0.506868 +0.397168 -0.364193 0.507995 +0.272714 -0.0415491 -0.502972 +-0.332361 0.281349 -0.518366 +0.472942 0.464097 -0.24921 +-0.513318 -0.0323707 -0.384076 +-0.490158 -0.156414 -0.0946257 +0.400613 -0.497394 0.456165 +-0.498758 0.377511 0.112161 +-0.50528 -0.0687386 -0.211307 +0.473604 -0.193239 -0.466733 +-0.495597 -0.129273 -0.232848 +-0.291439 -0.495025 0.0227188 +-0.49659 -0.154603 -0.0354937 +-0.0519244 0.490836 0.210173 +-0.402766 -0.511517 -0.413627 +-0.505565 -0.13235 -0.105925 +-0.492202 0.428451 -0.399714 +-0.473057 -0.469147 -0.472681 +-0.477974 -0.455328 0.463307 +-0.0724748 -0.219013 -0.495402 +0.165065 0.48299 0.474059 +0.494207 0.143602 0.46066 +-0.020288 -0.207155 -0.494425 +0.438011 0.23382 -0.502331 +-0.493096 -0.12835 -0.0494443 +0.217843 -0.492794 -0.25142 +-0.129822 -0.505188 -0.269238 +0.0976565 -0.498928 0.0846915 +0.426173 -0.492899 -0.111961 +0.405278 -0.500685 -0.171463 +-0.336592 -0.37002 -0.499913 +-0.357484 -0.408919 -0.512792 +-0.11634 -0.332219 0.512131 +0.514625 -0.324904 -0.420824 +0.517917 -0.265529 -0.339788 +-0.5069 0.202261 0.204463 +-0.494726 -0.269468 0.243882 +0.506063 0.0877241 -0.0435619 +0.266134 -0.511564 -0.194089 +-0.372813 -0.195506 -0.511122 +0.41672 0.209563 -0.49301 +-0.497168 -0.269871 -0.124468 +0.196477 0.204581 0.508175 +0.226294 0.203436 0.499656 +-0.259174 0.14494 0.496845 +-0.458899 -0.49561 -0.280464 +-0.418835 -0.0177665 0.495096 +-0.384779 -0.0628368 0.504001 +-0.390936 0.259433 -0.512746 +0.45385 0.00635432 -0.496728 +0.504004 0.172937 0.0451619 +0.505427 0.411383 0.222336 +0.498093 0.452019 0.250192 +0.508064 -0.164126 0.152395 +-0.503475 -0.328602 0.100428 +-0.102026 0.492223 0.249604 +-0.154312 0.137903 0.508819 +-0.497429 -0.345263 0.15422 +0.158196 -0.446672 0.492782 +-0.306946 -0.218403 -0.498558 +-0.275189 -0.286555 -0.505469 +-0.364699 0.323562 0.50929 +-0.508088 -0.0875654 0.429357 +0.486732 -0.000446275 0.45241 +-0.415045 -0.501709 0.173932 +-0.483047 -0.146269 0.477622 +0.151011 0.180669 0.492531 +-0.50458 0.404834 0.101662 +-0.502405 0.432165 0.152124 +-0.492987 0.418422 0.124769 +-0.498823 -0.183025 -0.22154 +-0.509143 -0.215498 -0.229034 +-0.498691 -0.106252 -0.250779 +-0.49838 -0.192286 -0.25369 +-0.112781 0.501306 -0.32986 +0.505184 -0.413901 0.390091 +-0.491515 -0.379043 -0.441971 +0.072737 -0.383047 0.506939 +-0.306909 0.501634 0.361475 +-0.2124 -0.162716 -0.508301 +-0.169993 -0.169272 -0.498704 +0.514815 0.304519 -0.378476 +0.511334 0.34103 -0.331072 +0.447562 0.486769 -0.141481 +-0.460685 -0.123214 -0.489835 +0.185163 0.427255 0.487892 +0.388086 0.211874 -0.503294 +0.483661 0.16871 0.469251 +-0.0873528 0.178827 0.491939 +0.385109 0.156634 -0.513716 +-0.513265 -0.177967 -0.406761 +0.501565 -0.110412 0.0429362 +-0.489734 -0.248066 -0.457627 +-0.472809 -0.485744 -0.175485 +0.460041 0.496942 -0.0883635 +0.472541 -0.194073 0.464146 +-0.505776 -0.249481 -0.439145 +-0.200354 -0.497689 0.329101 +-0.199982 0.343342 0.508255 +0.507292 0.123316 0.313497 +0.498722 0.201205 -0.289302 +0.491346 -0.223042 -0.162447 +0.501285 -0.241986 -0.140711 +0.0606688 -0.502434 0.159243 +-0.472057 0.325948 0.475065 +-0.502367 0.241179 -0.449031 +0.495605 -0.129621 0.0835068 +-0.501944 -0.225365 0.20649 +0.48162 -0.255134 0.467963 +0.445291 -0.422169 -0.489362 +-0.501853 -0.176752 0.276606 +-0.49115 -0.467358 0.31384 +-0.499186 -0.16649 0.302157 +-0.178722 -0.264883 -0.49269 +-0.460417 0.479057 0.144275 +-0.255347 0.103911 0.49231 +0.389867 -0.474359 -0.464663 +0.356866 -0.508492 0.0157508 +0.506213 -0.0536119 0.170448 +-0.0642113 -0.493422 0.0340411 +0.50544 0.2748 -0.195379 +-0.326083 -0.256018 -0.512941 +0.304941 0.0444245 0.509024 +0.497941 0.246481 -0.292693 +-0.476158 -0.168715 0.478529 +0.131764 0.487378 -0.469842 +0.0926226 0.493419 -0.110172 +0.245142 0.0281594 -0.504175 +-0.512513 -0.0880306 -0.359146 +0.478484 -0.43091 -0.478396 +0.340289 0.0432194 0.500538 +0.387039 0.0281084 0.496655 +-0.101926 0.50816 0.00512465 +0.511527 -0.0187949 -0.33817 +-0.501 0.433185 -0.03043 +0.114316 0.495832 0.207223 +-0.055686 -0.508718 -0.363961 +-0.00579505 -0.497103 -0.337964 +-0.51516 -0.350612 0.374697 +-0.500573 -0.364517 -0.374241 +-0.00303394 0.499869 -0.139116 +0.416265 -0.500232 -0.296664 +0.285325 -0.517853 -0.355671 +0.0732953 -0.505607 0.080185 +0.497198 0.431281 0.316599 +0.0760548 0.342551 0.499829 +0.0365127 0.278354 0.510324 +-0.348243 0.235873 0.504065 +-0.432159 0.504945 0.216018 +-0.276399 -0.512574 -0.355435 +-0.36838 -0.511524 -0.348399 +-0.509384 0.354377 -0.298903 +-0.333539 -0.510107 -0.306858 +-0.438644 0.469379 0.473778 +-0.363355 -0.513246 -0.317284 +0.0846642 -0.49483 0.179069 +0.185573 -0.495079 -0.29213 +0.133044 -0.506544 0.152766 +0.508064 -0.0502524 0.0357212 +0.508663 -0.0514375 0.0998542 +0.504544 -0.0213983 0.0864946 +-0.393625 -0.343069 -0.501942 +-0.314382 -0.0279209 0.496262 +-0.373881 -0.0379732 0.508571 +-0.283832 0.147358 0.493003 +-0.34035 0.0449152 0.512487 +-0.327426 0.170021 0.514052 +-0.332425 0.212113 0.509063 +0.129361 -0.50913 -0.22197 +-0.510441 0.368622 -0.408065 +-0.506452 -0.231673 0.00549911 +0.166065 -0.498964 -0.0736511 +-0.223353 -0.0217606 -0.492887 +0.136522 -0.503944 -0.0732114 +0.149785 -0.494787 -0.0974367 +0.0625942 0.296303 0.50291 +0.323692 -0.518446 -0.352285 +-0.0882905 -0.494549 0.408124 +-0.297591 0.301382 0.514363 +0.290485 -0.292053 0.513443 +0.352818 0.409954 -0.510281 +0.374385 0.503748 -0.4084 +0.0323905 -0.449828 -0.486142 +0.349218 0.439089 -0.492818 +0.0238064 0.506754 -0.416387 +0.478852 -0.0634477 0.453955 +-0.503756 -0.0285109 0.222388 +-0.00191144 0.5041 -0.436101 +0.514016 0.353104 -0.407991 +-0.236566 -0.242693 0.504421 +0.417877 0.504676 -0.423978 +-0.299905 -0.506228 -0.142316 +0.148245 -0.193378 0.504598 +0.195508 0.0970344 0.508065 +0.281288 0.20709 0.499458 +0.254039 0.203167 0.507613 +-0.277349 -0.508168 -0.0424632 +0.375137 -0.485863 -0.458447 +0.0524311 -0.390818 0.504151 +0.505585 0.211675 0.207691 +-0.0198806 -0.402529 0.494308 +0.00276749 -0.38519 0.499023 +0.494229 0.0856818 -0.0127181 +0.493595 0.119145 -0.0853003 +-0.41356 0.251659 -0.514939 +-0.499544 -0.0402019 0.145344 +-0.428315 -0.0471256 0.501035 +0.507155 0.424446 0.13865 +0.454282 0.493663 -0.0657734 +0.50481 -0.120749 -0.323311 +-0.18848 0.270375 -0.507793 +-0.161822 0.330179 -0.50485 +-0.157721 0.274345 -0.511297 +0.492085 0.015894 0.0353255 +0.506494 0.232329 -0.429031 +0.508646 0.309501 -0.0832999 +-0.257915 -0.336113 0.500246 +-0.505099 0.0248725 0.371219 +-0.502887 0.247784 -0.141283 +-0.496375 -0.0726928 0.369748 +0.491371 0.173796 0.00642275 +-0.503194 -0.0241051 0.308383 +-0.509569 -0.0311862 0.359086 +-0.512238 0.0157329 0.342242 +0.471787 -0.470439 0.422066 +-0.0219734 -0.374337 -0.514795 +-0.068638 -0.430012 -0.501377 +-0.0769957 -0.38367 -0.497321 +-0.461599 0.476216 -0.0349651 +-0.0585733 -0.404562 -0.495281 +0.225728 -0.191021 0.507815 +0.370929 0.375981 -0.504386 +-0.497065 -0.19433 -0.169789 +-0.493122 -0.240836 -0.110889 +0.433388 0.499846 0.257801 +0.40191 0.181974 -0.499836 +-0.287349 0.0772254 0.504809 +-0.18568 0.0734693 0.494304 +-0.232759 0.0529959 0.495551 +-0.044531 -0.313203 0.499146 +0.101686 0.260647 0.507118 +0.134304 0.262636 0.51193 +0.0618192 -0.508587 0.40334 +0.480732 0.472212 0.42852 +0.277734 0.0464298 -0.494688 +-0.131393 -0.394828 -0.506288 +-0.0384138 -0.310428 -0.50235 +0.226772 0.399941 -0.498519 +0.165014 0.402944 -0.495615 +0.386671 -0.034251 -0.495324 +0.382302 0.234433 0.501713 +0.385514 0.00980669 -0.499359 +-0.469182 -0.477987 0.402365 +0.343495 0.33035 0.519211 +0.44742 0.185213 0.482389 +0.49812 -0.411619 -0.450466 +-0.225096 0.515254 -0.319519 +0.185447 0.246264 -0.505626 +0.203481 0.208089 -0.50902 +-0.0504921 -0.286778 -0.496794 +-0.0883295 -0.471917 -0.485774 +-0.511108 -0.155171 -0.314819 +-0.313068 0.505514 0.173587 +-0.450008 0.485342 0.0109693 +-0.0936785 -0.272387 -0.510565 +-0.0655314 -0.265541 -0.494663 +-0.48472 -0.460283 -0.0471444 +-0.459561 -0.147164 0.485062 +0.501168 -0.411434 -0.0563679 +0.475159 0.482533 0.406517 +0.50645 -0.196418 -0.228013 +-0.497549 0.322367 -0.158212 +0.281653 0.0755141 -0.508674 +-0.0651342 0.500963 -0.216783 +-0.510558 0.0563903 0.296622 +0.374465 -0.385035 -0.515881 +0.493697 -0.421903 0.067147 +0.501158 0.210905 0.33033 +-0.334733 -0.497973 0.118782 +0.482426 0.373565 0.462212 +0.497537 0.218627 -0.239558 +0.254599 -0.403349 -0.503541 +-0.500815 -0.0206427 0.0895477 +0.257366 0.40006 -0.509966 +0.494348 -0.387063 0.441708 +-0.0436638 -0.506494 -0.298945 +-0.190683 0.464327 0.488259 +-0.0403667 -0.500925 -0.383246 +0.456095 -0.485947 0.167066 +0.10552 -0.502536 -0.413153 +-0.409801 -0.377615 0.505724 +-0.494376 -0.0511464 0.0971602 +0.498357 -0.403736 -0.423557 +0.490604 0.118468 -0.186363 +0.498911 0.118292 -0.209196 +0.495354 0.139511 -0.195538 +0.44639 -0.487066 0.128057 +0.48931 0.168346 0.415579 +0.161359 -0.506041 0.162648 +0.506756 -0.047375 0.316693 +-0.0689524 -0.0633408 -0.506302 +0.323632 0.311689 0.512121 +0.270142 0.513614 0.341896 +-0.34328 -0.509128 0.401932 +-0.346637 -0.440839 -0.491773 +0.508104 -0.0303666 -0.367561 +-0.116621 0.257164 -0.502329 +0.474834 0.467516 -0.405302 +-0.117334 0.228752 -0.508472 +-0.109191 -0.462035 0.490481 +0.386326 -0.507797 0.210456 +-0.49396 -0.0150184 -0.0597907 +0.48043 -0.383354 -0.456833 +-0.0866082 0.22094 -0.494561 +0.472558 -0.473164 -0.463599 +-0.503635 0.0799651 -0.384793 +0.0276425 -0.402224 0.510394 +0.0724055 0.189092 -0.500464 +0.0692612 -0.258092 0.506893 +-0.129628 0.278505 -0.497174 +0.491228 0.112814 0.00467091 +0.501373 0.271626 -0.382229 +-0.0522082 -0.143168 -0.49902 +-0.0319896 -0.161415 -0.498434 +-0.0570496 -0.169521 -0.495663 +-0.355277 0.515402 -0.173667 +-0.424127 -0.504655 -0.403313 +-0.509018 0.291277 -0.334691 +0.508946 0.0396428 0.0933825 +0.501428 0.00677584 0.106789 +0.492486 0.0370457 0.159952 +-0.505396 0.0354482 0.110136 +0.248655 -0.495781 0.425121 +0.262057 -0.502182 0.450451 +0.32748 0.45533 0.488677 +-0.193302 -0.497246 -0.143826 +0.488689 -0.458706 0.358279 +0.475332 0.00571628 -0.484882 +0.50534 -0.123258 -0.248709 +0.504446 -0.215638 -0.381563 +0.174226 -0.15686 0.502547 +-0.497071 -0.208666 0.425235 +-0.398131 0.469445 0.486114 +0.478525 0.412816 -0.481596 +-0.50139 -0.0687663 -0.179494 +0.381275 -0.511398 0.335841 +-0.499175 -0.316644 0.160065 +0.501674 -0.274403 -0.171943 +0.485962 -0.447318 -0.049331 +0.511659 0.0243385 -0.262851 +-0.503596 -0.124288 0.0625537 +0.41739 -0.389767 0.496942 +-0.380568 -0.450582 0.487211 +-0.161048 -0.493735 -0.222606 +-0.251869 -0.505065 -0.15946 +-0.505227 -0.313489 0.0456971 +-0.124285 -0.268221 -0.494176 +-0.50464 0.21341 0.323613 +-0.493217 -0.413837 -0.0856248 +-0.164197 -0.284613 -0.494422 +-0.0976456 -0.358878 -0.495595 +-0.1568 -0.34011 -0.499009 +0.300057 -0.514426 0.267197 +0.496076 0.0189681 -0.238471 +-0.495725 -0.277556 -0.154224 +-0.0226231 -0.499096 -0.279787 +0.319514 -0.512936 0.340872 +-0.503815 0.409791 -0.0958136 +0.495216 0.200029 0.130569 +-0.425997 0.233123 -0.500352 +-0.443996 0.241933 -0.490618 +0.178901 0.376571 -0.513824 +-0.454454 0.269973 -0.499628 +-0.47322 -0.48413 0.306528 +-0.471926 -0.436396 -0.482991 +0.499289 -0.255915 0.118352 +-0.433228 0.468795 -0.470897 +0.512152 -0.265548 0.0725534 +0.510644 -0.29774 0.0771665 +0.317345 -0.315871 -0.510407 +0.336548 0.519112 -0.324699 +-0.378728 -0.508968 0.294238 +-0.387836 -0.514712 0.321638 +-0.411521 -0.498823 0.324053 +0.175776 0.297884 -0.507485 +0.244663 -0.0123873 0.501597 +0.174689 -0.0166377 0.504642 +-0.330768 -0.515594 0.303422 +0.180076 -0.412191 -0.511938 +-0.48388 0.251015 -0.480853 +-0.379844 0.013825 0.513609 +-0.122937 -0.29478 0.493378 +-0.221956 0.328471 0.496403 +-0.271213 0.0917721 -0.508271 +-0.288622 0.133391 -0.49768 +-0.312989 0.0374607 -0.498082 +-0.332855 -0.46122 0.478484 +-0.130747 -0.454643 0.499174 +0.512839 -0.333728 0.0838793 +-0.495548 0.436355 -0.24061 +-0.494554 0.427411 -0.215674 +-0.455553 -0.477085 -0.410732 +0.241303 0.0752598 0.499121 +0.258389 0.0172117 0.492545 +0.203354 0.0413728 0.506464 +0.432436 0.376358 0.490925 +0.260757 0.0660629 0.499968 +0.497359 0.286574 0.0621102 +0.496693 0.310448 0.0483812 +0.465103 0.0763668 0.474212 +-0.511665 -0.353627 0.122884 +-0.291856 -0.482705 0.451535 +-0.505258 0.128046 0.0445934 +0.503518 0.240066 0.0888342 +0.505419 -0.355203 -0.306612 +0.384764 0.485361 0.460995 +-0.49549 0.253873 0.0559785 +-0.491061 0.199394 0.0108215 +0.265115 -0.503136 0.401649 +-0.494707 0.249497 0.0284709 +0.0146278 -0.504642 -0.432428 +0.0424083 -0.500425 -0.388079 +0.493249 -0.182852 0.210567 +0.502015 -0.446083 0.399641 +0.0636965 -0.490578 -0.428219 +-0.501603 0.148723 -0.403564 +0.49304 -0.199038 0.0184961 +0.497573 -0.251213 -0.0559293 +-0.494181 0.189917 -0.437788 +-0.494281 0.218905 -0.411746 +-0.398892 -0.195284 -0.507416 +0.495686 -0.166117 0.446829 +0.420029 -0.375866 -0.495593 +-0.486156 -0.443612 0.0746036 +0.508066 0.113306 -0.34261 +0.100948 -0.174053 0.506794 +0.274954 0.497952 0.0596761 +-0.464385 -0.0138223 0.469935 +0.497644 -0.313767 -0.228424 +0.0292242 -0.498681 0.170827 +0.366784 0.479257 -0.464432 +-0.512778 -0.374487 0.0235289 +-0.0893253 0.0749022 0.500462 +-0.376657 0.429386 -0.491002 +0.483701 -0.120162 -0.465385 +-0.280431 0.240735 -0.512047 +0.142072 -0.346132 -0.5078 +-0.236057 -0.506857 0.206538 +-0.473892 -0.48758 -0.301379 +-0.490893 -0.368173 0.424964 +0.0858705 -0.366598 -0.513164 +0.514021 -0.374386 -0.384799 +-0.482994 -0.459223 0.136412 +0.500036 -0.318149 -0.39342 +-0.508465 0.298321 0.0874822 +-0.501096 -0.40027 0.0431823 +-0.485509 -0.460579 0.0906095 +0.511729 -0.0111376 -0.391324 +0.400497 -0.509486 -0.0454038 +-0.513989 -0.317902 -0.39725 +-0.417011 0.162267 -0.509771 +-0.499758 -0.212195 -0.0940684 +-0.498438 -0.175207 0.00312356 +0.104082 -0.422931 -0.506971 +-0.502676 -0.211954 -0.151301 +0.491137 -0.0562908 -0.121564 +-0.514974 -0.375521 -0.348958 +-0.121924 -0.51373 -0.378547 +-0.498485 0.327773 -0.404003 +0.211654 0.125001 0.508012 +0.502068 0.303003 -0.204562 +-0.49624 0.436387 0.0204303 +0.511517 0.326833 -0.165834 +-0.502401 -0.449401 0.176771 +-0.503311 -0.427377 0.133046 +-0.502607 -0.402288 0.190951 +-0.510627 -0.407991 -0.312085 +0.494405 -0.0725631 -0.145285 +0.481635 0.227793 0.452058 +-0.509717 -0.0245567 -0.355254 +0.496113 0.239463 -0.131632 +0.164797 0.154031 0.491587 +0.241727 -0.153169 -0.500584 +0.285182 -0.126881 -0.503666 +-0.492874 -0.176871 0.426103 +0.254451 -0.126638 -0.495831 +-0.487321 -0.438354 0.267773 +-0.513084 0.389639 0.301045 +0.501958 -0.348065 -0.332927 +0.468822 -0.486889 0.0844608 +0.020874 -0.501605 -0.235572 +0.111053 -0.509329 -0.205189 +-0.18889 0.371565 0.49956 +0.0269083 -0.512815 -0.295207 +0.0719587 -0.50906 -0.235665 +-0.0602856 -0.467745 -0.489372 +0.480143 -0.298477 0.460879 +0.507721 0.169928 0.383946 +-0.339529 0.146232 -0.511361 +-0.353071 0.0847134 -0.499452 +-0.400814 0.505236 0.371562 +-0.495912 0.412136 0.0240677 +-0.413182 -0.505634 0.0687755 +-0.473014 -0.346847 -0.481181 +0.35165 0.437448 0.490277 +-0.389073 -0.500937 0.0790028 +0.388277 0.44625 0.499389 +-0.369302 -0.514626 0.0621066 +-0.501032 -0.173621 -0.191342 +0.375333 -0.292329 -0.500703 +-0.0410981 0.509067 0.369549 +-0.505652 0.154129 -0.129171 +-0.302511 -0.461251 0.479683 +-0.5 -0.394664 0.302097 +0.101254 -0.503109 0.334352 +0.116804 -0.503781 0.375959 +-0.0704575 0.503749 -0.336466 +0.49833 0.0574805 0.000282479 +-0.495698 -0.133591 -0.294303 +-0.501466 -0.237544 0.117601 +0.0652303 -0.499177 0.372994 +0.0544928 -0.441021 0.498379 +0.37909 -0.413467 -0.503453 +-0.497968 -0.138976 0.037772 +0.501253 -0.111066 0.166963 +-0.393822 -0.501206 -0.0976235 +0.489238 0.410337 -0.449995 +-0.505897 0.0386758 -0.279721 +0.102145 -0.266524 -0.494755 +0.477894 0.398741 -0.462772 +-0.487913 -0.222488 -0.470455 +0.127781 -0.312997 -0.509092 +-0.325556 -0.500584 0.173846 +-0.233698 -0.146877 -0.50161 +-0.259197 -0.111266 -0.495899 +-0.499982 0.0309324 -0.247798 +0.294252 0.464676 0.492206 +-0.335525 0.498423 -0.40073 +0.114925 -0.470942 0.473324 +0.393772 0.502367 0.136244 +0.130507 -0.494487 -0.419321 +-0.496571 0.353542 0.159497 +-0.494581 -0.0959122 -0.192341 +0.108751 -0.454168 0.48644 +-0.210772 0.490328 0.440868 +-0.505108 -0.262822 0.131953 +-0.506864 -0.0500956 -0.237704 +0.506128 -0.294087 -0.159719 +0.493664 -0.263849 -0.0870145 +-0.0379708 -0.463528 -0.493789 +-0.0251144 -0.442035 -0.486812 +0.0713277 0.494497 0.170788 +-0.500707 -0.131903 -0.156641 +-0.0369156 0.194294 0.503612 +-0.00712835 -0.421987 -0.502719 +-0.461389 -0.478675 -0.334277 +-0.464477 0.470895 0.334698 +-0.423044 0.299158 0.509885 +-0.3505 -0.514821 -0.398298 +-0.326597 -0.499108 -0.415033 +-0.484216 0.447122 0.30381 +-0.457862 0.489152 0.307753 +0.509037 0.167589 0.0988368 +0.372683 0.00711979 0.501581 +0.0665111 0.50097 -0.345158 +-0.494348 0.207577 0.126226 +0.504425 0.153983 0.154276 +-0.242018 -0.355705 -0.499101 +-0.498746 0.274147 -0.183594 +0.498368 -0.102451 0.345796 +0.418956 0.502342 0.390475 +-0.135179 -0.318511 -0.503901 +-0.0276931 0.204294 -0.493716 +-0.243038 -0.276352 -0.511192 +-0.489377 0.323608 -0.474654 +-0.186742 -0.326934 -0.502284 +0.00261246 0.349768 -0.504982 +0.505484 -0.164349 -0.260562 +0.107171 -0.490205 -0.0766585 +-0.502207 -0.426906 -0.334349 +-0.453452 -0.469255 0.472092 +0.135378 -0.487711 -0.441095 +0.239188 0.512917 0.378668 +0.301292 0.480138 -0.459232 +0.486922 -0.470425 -0.117897 +0.283436 0.476893 0.47037 +0.500522 0.180789 -0.414963 +0.478017 0.242807 -0.486325 +0.503526 0.294142 0.213422 +0.258477 -0.496851 -0.0968609 +-0.197673 0.489913 -0.439817 +0.290636 -0.262016 0.505925 +0.364362 0.103879 -0.514802 +0.260877 -0.226743 0.49717 +0.510452 -0.128789 -0.293831 +-0.0779271 -0.176995 -0.494856 +-0.498176 -0.0614367 -0.150855 +-0.206349 -0.397855 0.507768 +-0.50311 -0.322638 0.0201947 +-0.469246 -0.486584 -0.38601 +-0.0428687 0.486397 -0.471347 +-0.210182 -0.355542 0.496488 +0.311266 -0.0813131 0.498762 +-0.317803 -0.494426 -0.46487 +0.254104 -0.0662496 0.508127 +-0.156985 -0.41417 0.49419 +-0.502667 -0.206134 0.38269 +-0.503276 -0.219635 0.36102 +-0.337457 -0.112748 0.51273 +-0.378803 -0.131036 0.502755 +-0.135306 -0.239523 -0.509241 +-0.195526 -0.238127 -0.501242 +-0.237368 0.473483 0.48109 +-0.256266 -0.254413 0.509846 +-0.0352998 0.326352 -0.508458 +-0.0115156 0.2586 -0.501435 +-0.0468517 0.416625 -0.496599 +-0.043153 0.267851 -0.494601 +0.274073 -0.432334 0.49892 +0.268478 -0.249508 0.508975 +0.197927 -0.179934 0.497645 +0.0641292 -0.504103 0.0524984 +0.485781 0.446895 -0.259796 +-0.448371 0.0277353 0.490561 +-0.509527 0.37647 0.433511 +0.487951 -0.443057 -0.025927 +-0.504385 0.225691 0.0452147 +-0.50268 0.319129 0.114573 +-0.323081 0.344291 -0.51525 +0.492564 -0.120925 0.244413 +-0.497544 0.392782 0.410379 +0.50365 -0.00214382 -0.260687 +-0.492523 -0.425174 0.198503 +0.502458 -0.393746 0.0643569 +0.500877 -0.123931 0.014887 +0.372027 -0.353447 -0.518878 +0.255077 -0.503136 -0.0260753 +0.0652869 0.217464 -0.508557 +0.30973 -0.500215 -0.0166739 +0.483797 -0.22025 -0.459664 +0.401802 -0.140534 0.499049 +0.498686 0.398216 0.195964 +0.0900121 -0.509915 0.418987 +-0.508893 0.216991 -0.0553251 +0.0552168 0.0457512 0.490211 +0.507461 0.312343 0.0209784 +0.500314 0.261988 -0.0102437 +0.497414 0.262437 0.0770312 +0.510256 0.312743 -0.0043595 +-0.514439 -0.236153 -0.322989 +-0.496194 0.0481201 -0.340966 +-0.345062 -0.476495 0.465629 +0.122327 -0.501939 -0.0133257 +-0.505289 0.270336 0.333544 +-0.358514 -0.495542 0.450024 +-0.43067 -0.304321 -0.502498 +0.505255 -0.364689 -0.147063 +-0.495073 0.144009 0.106881 +0.195402 0.514297 0.377523 +0.496542 0.382267 0.431595 +0.498988 0.164667 -0.248137 +-0.137806 -0.491365 -0.119974 +0.387696 0.269018 0.514718 +0.41473 0.280136 0.503498 +0.0845835 -0.500148 0.105027 +-0.49861 -0.0634968 0.147601 +-0.189776 -0.500152 -0.226913 +-0.218586 -0.494076 -0.231904 +-0.26009 -0.501965 -0.253593 +-0.513015 0.277908 -0.315108 +0.190287 -0.501259 0.0818458 +0.113148 -0.501599 -0.433626 +-0.490459 0.195083 -0.065213 +0.332287 -0.493432 -0.455335 +-0.357658 0.120625 0.508126 +-0.41646 -0.490074 -0.115455 +-0.344114 -0.111093 -0.498424 +-0.495141 0.30465 -0.0428723 +-0.497778 0.228699 -0.202841 +-0.470892 0.483602 -0.431982 +-0.508459 0.177528 -0.109859 +0.503383 0.0815848 0.329872 +0.493762 0.0518394 0.028949 +0.505894 -0.156137 0.312085 +0.512366 -0.207481 0.366508 +0.349849 -0.491109 -0.469189 +0.379622 -0.49779 -0.133609 +0.0269564 -0.495258 -0.0882346 +-0.491824 -0.180425 -0.0489517 +-0.491685 -0.177876 -0.0226398 +0.41999 0.0867247 -0.501787 +0.151532 0.297414 0.503745 +0.449324 0.056451 -0.483891 +0.437826 0.098488 -0.495286 +-0.495232 -0.00604451 -0.384184 +0.504975 0.0332467 0.0105998 +0.422921 0.435644 0.500161 +-0.496732 -0.0790995 -0.431566 +0.359006 0.513986 0.220393 +-0.50101 -0.153332 -0.394141 +0.447819 -0.489331 0.352813 +-0.28838 0.198561 0.502405 +-0.492573 -0.0952923 -0.409091 +0.10464 0.380463 0.50091 +0.51485 -0.175414 -0.337662 +0.508893 0.337971 0.199068 +0.504595 0.347015 0.246284 +0.492623 0.103517 -0.163628 +-0.366163 -0.510366 0.0877023 +0.011113 0.506209 -0.259132 +-0.433009 0.139043 -0.491254 +-0.368926 -0.509046 -0.0268241 +-0.346338 -0.498723 0.0486663 +-0.444755 -0.488119 0.144902 +-0.0367563 -0.45888 0.48142 +0.218733 -0.514119 -0.383047 +0.329662 -0.502415 -0.313448 +-0.505863 -0.316701 0.383132 +0.181862 0.477225 -0.462993 +-0.46112 0.46774 -0.449265 +-0.067509 0.503197 0.410968 +0.510851 0.356892 -0.102995 +0.507541 -0.0312414 0.269858 +0.446974 -0.496836 0.058408 +0.153587 0.494072 0.147027 +0.183848 0.505216 0.142885 +-0.506301 0.273466 0.391715 +0.478878 -0.457907 0.1889 +0.495495 -0.208401 -0.134284 +-0.412379 -0.498636 -0.208837 +0.376323 0.500226 -0.432829 +-0.506798 0.291775 0.221158 +0.505251 0.077507 0.0492681 +-0.505327 -0.107011 -0.386393 +0.508897 -0.0726445 0.248012 +0.40782 0.508419 0.0655206 +0.494164 -0.0698091 0.22025 +0.494991 -0.036488 0.145684 +0.507606 -0.0964164 0.184788 +-0.505438 0.433956 0.0966804 +-0.447747 -0.479788 0.0713311 +-0.20463 -0.429128 -0.488598 +0.502308 -0.0354225 -0.180504 +0.143229 -0.495583 -0.2752 +0.497979 -0.424396 -0.261161 +0.288109 -0.324915 0.515909 +0.018013 -0.494582 0.272015 +-0.222423 -0.505218 0.275889 +-0.495224 -0.153081 -0.128425 +0.134773 0.497408 0.405956 +0.412649 -0.482666 -0.474912 +-0.508975 -0.402598 -0.196943 +0.175917 -0.0867915 0.490483 +-0.476684 -0.471195 0.441074 +-0.247846 -0.505393 -0.283244 +-0.171096 -0.497173 -0.249482 +-0.181365 -0.502621 -0.309959 +-0.148708 -0.512652 -0.295596 +-0.0612845 -0.504288 0.325516 +-0.476395 0.446149 0.470899 +0.0722785 0.495467 -0.0477334 +0.108996 -0.509969 0.226815 +0.0935712 -0.501108 0.361631 +0.4158 0.113404 -0.492164 +0.0978864 0.360383 -0.505021 +0.348621 -0.498854 -0.0938444 +0.279135 -0.508967 -0.0220896 +0.349721 -0.509674 0.121479 +0.32561 -0.50354 0.111807 +0.511665 0.365567 -0.243735 +0.0877882 0.452333 -0.495287 +0.123961 0.431589 -0.497446 +0.47152 0.484767 0.287911 +0.205474 -0.300753 0.500297 +-0.471854 -0.477717 -0.0564901 +0.22853 -0.352098 0.501329 +0.498859 0.314811 0.201737 +0.426143 0.501195 -0.165391 +-0.13935 -0.358987 0.511664 +0.502605 0.301142 0.422252 +0.431227 -0.490523 0.330744 +-0.156317 0.216084 0.503869 +0.453379 0.481679 -0.210134 +-0.175855 0.491648 -0.419887 +-0.205029 0.239689 0.497566 +-0.200537 0.211358 0.506888 +0.28873 -0.500328 0.00546794 +0.372296 -0.509801 -0.0107733 +-0.385967 -0.367188 0.515167 +-0.0691056 0.506652 -0.0509191 +-0.503664 0.409125 -0.311392 +-0.497345 0.401086 -0.283781 +0.124732 -0.273793 0.508908 +0.0833372 -0.313447 0.507842 +-0.459356 0.473004 0.43876 +-0.49676 -0.0737752 0.076242 +0.198787 -0.22012 -0.507206 +0.0807392 -0.241666 -0.510612 +-0.474524 0.462365 0.35893 +0.150196 -0.235411 -0.496591 +-0.447112 -0.418376 -0.49871 +-0.506394 0.415956 0.0730864 +-0.482565 -0.472808 -0.248496 +0.179188 -0.241141 -0.501935 +0.497222 0.348844 -0.0500864 +0.500331 -0.0457497 -0.415927 +0.506951 -0.172477 -0.234145 +-0.48639 0.453412 -0.322067 +0.492829 -0.210715 0.119581 +-0.50934 -0.174315 -0.344924 +0.386093 -0.39516 0.511619 +0.495284 0.235457 0.230299 +0.403545 0.374136 -0.502541 +-0.49713 0.305616 0.163762 +0.476385 -0.464019 0.132757 +-0.5089 0.223042 0.402436 +-0.0156228 0.171105 -0.508914 +-0.512083 0.365037 0.306079 +0.502951 0.139607 -0.394865 +0.510544 0.379527 0.0464054 +-0.00373798 0.498382 -0.188492 +0.12406 -0.137363 -0.506036 +0.511875 0.351989 0.0837877 +0.498146 0.290738 0.0922503 +0.504056 0.31166 0.116289 +0.514418 0.330877 0.0645532 +-0.507545 0.339562 -0.134562 +-0.502275 0.376729 -0.156589 +-0.512583 0.401678 0.0487922 +-0.51003 0.351008 0.0974988 +0.406988 -0.422458 -0.503005 +-0.508891 0.372218 0.0444027 +-0.507281 0.267569 -0.341102 +0.498053 0.160634 -0.180251 +0.186002 0.494455 -0.184702 +0.505301 0.00645326 0.302045 +-0.278688 -0.513905 0.310111 +-0.492957 -0.0868182 -0.266175 +-0.508845 -0.133761 -0.263051 +-0.406999 -0.512349 0.224318 +-0.139018 -0.503991 0.186921 +-0.088812 0.340431 0.508141 +0.0363186 0.377115 -0.497465 +0.0442584 0.331783 -0.496996 +-0.510777 -0.112031 -0.335469 +0.496759 -0.140808 0.0412256 +0.511015 -0.101473 0.315523 +0.0554316 -0.166601 -0.504608 +-0.451872 0.480962 -0.46524 +0.10738 -0.499161 -0.307697 +0.496695 -0.438546 0.371057 +0.499566 -0.124393 0.270691 +-0.446727 -0.369784 0.486667 +0.141373 -0.495826 0.104539 +-0.28076 -0.505925 -0.165058 +-0.303715 -0.507701 -0.219284 +0.348075 0.128201 0.50118 +0.382638 0.0753796 0.500142 +0.395773 0.10061 0.493109 +0.226978 0.496818 -0.212511 +0.489358 -0.155908 -0.162716 +0.496282 0.453687 0.384766 +0.513364 0.385672 0.407622 +-0.505153 -0.171782 0.333111 +-0.494018 -0.187095 0.24692 +0.10877 0.485751 0.441461 +0.490698 0.176105 0.141971 +0.508986 0.089578 -0.423145 +0.500104 0.0016782 -0.363678 +0.513979 0.0608479 -0.351725 +0.512807 0.0866654 -0.3939 +-0.306926 -0.513622 0.124464 +-0.277233 -0.50451 0.130522 +-0.447509 0.402571 -0.483139 +-0.301453 -0.496025 0.153732 +0.341803 -0.23419 0.503787 +0.424943 -0.154647 0.497763 +0.508506 -0.073215 0.191586 +0.492337 -0.148598 0.205797 +0.504127 -0.184122 0.382274 +0.434844 0.328867 -0.495127 +-0.450745 0.0885726 -0.493904 +-0.50512 0.189254 -0.132285 +0.498936 0.0977785 0.402584 +0.101137 0.438962 -0.506309 +0.0600237 0.447867 -0.491304 +-0.51437 0.206448 -0.394576 +-0.500722 0.131272 -0.355944 +-0.510567 0.189597 -0.366422 +0.508376 0.151897 0.125016 +0.500146 0.120112 0.123724 +0.510503 -0.0905871 -0.331278 +-0.387557 -0.511054 -0.296138 +0.495515 0.442114 0.407953 +0.495301 -0.0521411 0.124824 +0.505135 -0.172564 0.181767 +0.163905 -0.208309 0.503221 +0.20537 -0.208491 0.49773 +-0.431498 0.107811 -0.503394 +0.11671 -0.371781 -0.513113 +0.182289 -0.25125 0.497833 +-0.512381 0.392064 -0.331372 +-0.477625 0.482398 -0.147924 +0.422861 0.510275 0.302354 +-0.507084 0.157818 0.237635 +0.208728 -0.237206 0.491972 +-0.505595 -0.337302 0.321124 +0.304659 0.288654 0.502867 +-0.0724112 0.488638 -0.474944 +-0.349996 0.337441 -0.508804 +-0.510475 -0.260069 0.345097 +-0.503044 -0.308584 0.329437 +0.497838 -0.104039 0.374882 +0.315689 0.504583 -0.226495 +0.503724 -0.100338 0.28686 +-0.42938 0.483105 0.444439 +0.513611 -0.183161 0.327554 +0.438455 0.0373128 0.495395 +0.498444 0.236489 -0.0505643 +0.503889 0.233291 0.00566522 +0.347791 -0.174895 0.504248 +-0.179193 0.127163 -0.507626 +-0.235269 0.132451 -0.498747 +-0.191129 0.152734 -0.492102 +-0.279278 -0.134446 -0.501048 +0.488567 0.466537 0.331101 +0.514158 -0.251432 -0.395376 +-0.496322 0.305834 -0.184366 +0.0473397 -0.497613 -0.335246 +0.0961798 -0.509108 -0.354895 +0.185039 -0.495313 -0.317423 +0.498647 -0.018943 0.0530925 +0.493532 0.436857 0.169984 +-0.304935 0.51417 0.249553 +-0.495327 -0.203771 -0.436534 +-0.299086 -0.150968 0.498265 +0.371337 -0.0548913 -0.495201 +0.382916 -0.082501 -0.508049 +-0.498697 -0.161977 0.0988135 +-0.509109 -0.141851 0.114074 +0.493213 -0.159048 0.0156675 +0.191625 -0.466167 0.472168 +-0.493415 -0.138319 0.160142 +-0.494728 -0.137841 0.137209 +0.500518 0.0917069 0.130689 +0.504642 0.0883959 0.154194 +0.497438 0.0655163 0.20815 +-0.502382 -0.280996 0.0529321 +0.126233 0.500368 -0.317476 +-0.307673 0.509071 0.10819 +0.492173 0.0942747 0.200735 +-0.504279 0.437176 0.256571 +-0.476441 0.477666 0.185207 +-0.321911 0.356399 0.509546 +0.296223 -0.410346 -0.513406 +-0.345081 0.48389 -0.452436 +-0.31011 0.194346 -0.500483 +-0.510322 0.414691 0.243204 +0.100424 -0.499068 -0.385498 +0.23888 0.411077 0.501762 +0.502264 -0.412712 0.230153 +0.316401 -0.391422 -0.502289 +-0.509065 -0.415347 0.110944 +0.490665 -0.165827 -0.466887 +-0.367245 0.134119 -0.50023 +-0.494024 -0.0152524 0.0619817 +0.0120952 0.281746 -0.495651 +-0.182556 0.443222 -0.489945 +-0.113545 0.507448 0.18931 +-0.508912 -0.237448 0.338306 +0.436585 -0.359836 -0.496088 +0.396737 -0.498666 0.3093 +-0.00103188 0.481417 0.472473 +0.387439 -0.504429 0.244416 +0.417032 -0.500356 0.288715 +0.259496 0.497745 -0.0597839 +0.499311 -0.319954 0.0463437 +0.50717 0.0207211 0.270927 +-0.240829 0.512335 -0.380903 +0.441047 0.495299 0.39226 +0.502577 0.113579 0.287004 +0.510655 0.0552721 0.276348 +-0.496006 -0.336243 0.430745 +0.492948 -0.0578589 -0.1982 +-0.361089 0.264594 0.505977 +-0.31858 -0.415943 0.498984 +-0.0433763 0.454721 -0.485566 +-0.015486 0.418171 -0.505481 +-0.0135359 0.369429 -0.495962 +0.0215454 0.393109 -0.503686 +0.173998 0.492344 0.0219957 +0.029427 0.444496 -0.495258 +-0.149522 0.162109 0.504138 +0.510527 0.422052 -0.304813 +0.48005 0.46634 -0.281191 +-0.273755 0.512382 -0.0930237 +0.161992 -0.0930757 -0.493281 +0.456631 0.340933 -0.497076 +-0.495643 -0.241021 -0.0798033 +-0.376707 0.501103 -0.35019 +-0.495611 -0.428273 0.0894532 +-0.503902 -0.344302 0.0367101 +0.380199 -0.124542 0.498028 +0.398231 -0.482718 -0.453361 +-0.411344 -0.124639 0.509315 +-0.380864 0.237873 0.506289 +-0.474219 0.470988 0.163095 +-0.33856 -0.501519 0.336349 +0.495118 -0.19884 -0.160424 +0.492615 -0.179467 -0.174549 +0.503082 -0.212995 -0.209382 +0.265424 -0.512867 -0.331236 +-0.207315 -0.495356 0.40628 +-0.255229 -0.51539 0.356408 +-0.236387 -0.512876 0.407229 +-0.282952 -0.507737 0.378516 +0.491998 0.0691326 -0.0914691 +-0.128125 0.395603 -0.498116 +-0.0812695 0.418786 -0.496407 +-0.123456 0.418914 -0.495782 +0.164157 -0.508863 -0.370199 +0.500581 -0.255795 0.0502245 +0.214831 -0.501613 -0.437522 +0.146492 -0.501929 -0.407484 +0.499551 -0.39891 0.419103 +-0.286953 0.0182737 0.499761 +0.498455 0.0824416 0.017968 +-0.259864 0.0348649 0.503749 +-0.20361 0.0114492 0.49083 +-0.22789 -0.00884917 0.50391 +-0.422955 -0.502999 0.149275 +-0.488938 -0.445669 -0.241541 +0.491722 -0.152022 -0.215399 +0.506655 -0.137421 -0.175586 +-0.480209 -0.438165 -0.463148 +0.489155 -0.156234 -0.188472 +0.246989 -0.500004 0.0940453 +0.31059 -0.511094 0.147494 +0.160188 -0.498 0.345335 +0.293932 -0.507682 0.0336077 +0.277778 -0.492953 0.108634 +-0.409904 -0.0672219 0.507101 +0.270498 -0.353294 -0.507727 +0.378557 0.428722 -0.48948 +-0.391882 -0.511456 -0.3274 +-0.498109 -0.14632 0.202849 +-0.502736 -0.0889009 0.213802 +-0.314171 -0.100004 0.510133 +0.0227271 0.502699 0.21946 +-0.508884 -0.108051 0.237145 +-0.460514 0.497365 -0.367976 +0.501295 -0.321801 0.0135779 +0.087213 0.474094 -0.473136 +-0.276069 0.274774 -0.510681 +-0.409343 0.3125 -0.510752 +-0.411853 0.279033 -0.510228 +-0.375181 0.213783 -0.498377 +-0.362709 0.27005 -0.502328 +-0.0392246 -0.261629 -0.498043 +0.0381371 -0.279729 -0.494759 +0.374536 -0.512289 -0.10598 +0.0283315 -0.363249 -0.495704 +0.498718 -0.117831 -0.0965471 +0.459292 -0.495972 -0.392627 +0.0999983 0.471131 -0.490813 +0.0246052 -0.310338 -0.512568 +-0.512877 0.045368 -0.310024 +0.41283 -0.443114 -0.488735 +-0.365723 0.510664 0.196442 +-0.314168 0.00239186 0.495724 +0.441371 -0.474869 -0.445796 +-0.507829 0.134732 0.405085 +-0.509074 0.165439 0.403552 +-0.499653 0.151914 0.427787 +0.253555 0.508832 0.0165136 +0.261347 -0.306266 0.505552 +0.355209 -0.435182 -0.508267 +0.492962 0.451106 0.314632 +-0.495823 0.245161 -0.182078 +-0.501641 0.204738 -0.157254 +-0.128342 -0.494088 -0.436583 +-0.472111 0.465676 0.426085 +-0.181908 -0.511004 -0.407563 +-0.509097 -0.0446984 0.400474 +-0.51067 -0.256274 0.195379 +-0.10139 -0.50495 -0.268706 +0.506252 0.404411 0.354003 +-0.497417 -0.0629783 0.461093 +-0.123432 -0.0300233 -0.506328 +-0.500926 -0.406591 -0.446529 +0.142278 0.47296 0.460138 +-0.503233 -0.168683 0.0315735 +-0.465355 -0.320384 0.491802 +-0.236075 -0.50736 -0.309763 +-0.306974 0.328857 0.510538 +0.503959 0.192902 -0.0913627 +0.505751 -0.34068 -0.00739039 +0.502351 0.243753 -0.190113 +-0.497995 -0.359235 0.236179 +0.112382 -0.0890947 0.494842 +0.125698 -0.110179 0.501629 +0.0853063 -0.128355 0.492135 +0.0574764 -0.317635 0.49573 +0.499378 -0.42405 -0.292567 +0.4076 0.506822 0.189282 +0.385327 0.514338 0.204246 +0.474025 0.48487 0.320423 +0.492128 0.46135 0.358908 +0.321811 -0.506311 0.403508 +-0.0298964 0.481066 0.453831 +0.428867 0.49416 0.200297 +0.294189 -0.513377 0.411377 +0.397534 0.448707 -0.486048 +-0.352859 -0.496696 0.422008 +-0.308867 -0.501261 0.435558 +0.301575 -0.503312 -0.383754 +0.25798 -0.51144 -0.409374 +0.275103 -0.482977 -0.44958 +0.157905 0.0951832 0.494469 +0.510433 0.244147 -0.359979 +0.151082 0.0610579 0.506662 +-0.240852 -0.504106 -0.339203 +-0.367167 -0.0834986 -0.502009 +0.512696 -0.304586 -0.369247 +0.0119271 0.48191 -0.479721 +0.500017 -0.114824 0.455328 +-0.483359 -0.159896 0.459224 +-0.502267 -0.266335 0.410243 +-0.0286223 -0.505284 0.381861 +0.164621 -0.465115 0.480502 +-0.497823 -0.281592 0.446725 +0.207263 -0.414322 -0.495561 +-0.50838 -0.268774 0.386074 +0.218661 -0.369038 -0.511437 +0.504583 0.406697 -0.113286 +0.500625 0.387787 -0.0258283 +0.42454 -0.502574 0.0720436 +-0.434018 -0.498578 -0.290855 +-0.0220602 0.0460578 0.509215 +0.332521 -0.448153 -0.486092 +0.339764 0.473306 0.480652 +0.500669 0.292022 0.247291 +-0.105151 0.13937 0.490209 +0.510621 0.24265 0.199741 +0.500385 0.254598 0.13457 +0.503532 0.225295 0.146858 +0.458349 0.481993 -0.0459563 +0.49914 0.2723 0.194293 +-0.30809 0.213831 0.509731 +-0.429245 0.0387146 0.498496 +-0.339626 0.19066 0.495865 +0.471314 0.326534 -0.485033 +-0.0214737 0.117275 0.506229 +0.21251 0.322916 -0.503111 +-0.344136 -0.500829 -0.0430048 +0.381486 0.510043 0.0303522 +0.117693 0.496879 0.180324 +0.167632 -0.153158 -0.502218 +0.489357 0.264823 -0.438722 +0.118652 -0.398222 0.512129 +0.115507 -0.36783 0.49718 +0.415099 -0.258827 0.509869 +0.0993571 -0.339902 0.496205 +-0.121871 -0.489125 0.462119 +0.145304 -0.357298 0.506978 +0.506271 0.396761 0.120716 +-0.474819 -0.251961 0.486159 +-0.472178 -0.464517 -0.445248 +0.496495 0.326223 0.134997 +0.157619 -0.507546 -0.122188 +0.241156 -0.499787 -0.149217 +0.189217 -0.503871 -0.160235 +0.0847495 -0.210507 -0.494104 +0.491975 -0.274467 0.458554 +-0.492695 0.183834 -0.460424 +0.508529 -0.268117 0.415064 +0.496727 -0.215053 0.417495 +0.507478 -0.158993 0.123189 +-0.494928 -0.345174 -0.0316903 +0.288756 0.517699 0.321468 +-0.504616 -0.317892 -0.255126 +0.491426 -0.235522 -0.110188 +-0.341763 -0.506891 0.0929591 +0.212906 0.494513 0.135037 +-0.0688216 -0.502992 0.380092 +-0.159581 -0.510317 0.405326 +0.220103 0.281267 0.513502 +0.0537843 -0.436585 -0.50106 +0.150942 0.23385 0.500931 +0.497779 0.00419287 0.385078 +-0.353167 0.510334 -0.113847 +-0.497975 -0.430736 -0.00535516 +0.511062 -0.0983625 0.258957 +-0.252726 0.507079 -0.101983 +0.382433 -0.501316 -0.0325294 +0.505691 -0.188115 0.293129 +0.462796 -0.292532 -0.483924 +-0.466198 0.475517 -0.379287 +0.508581 -0.146272 0.252735 +-0.507629 0.24288 0.326911 +-0.46204 0.393457 -0.477392 +0.45454 -0.48615 0.322001 +0.494814 0.109289 0.0370453 +-0.295792 0.500915 0.0852716 +0.507995 -0.162621 0.424987 +0.502784 0.449608 -0.102815 +0.283822 0.150911 -0.493165 +-0.205868 -0.480951 0.451625 +0.512405 -0.331061 -0.195871 +0.491739 0.420419 -0.0647681 +0.493528 0.114131 -0.404869 +-0.50043 -0.245115 0.39534 +-0.49335 -0.287842 0.421906 +0.507579 0.391483 0.268694 +0.481836 -0.44971 -0.454339 +0.478086 -0.0132007 0.470595 +0.484421 0.452122 -0.44945 +0.506888 0.384147 0.301899 +0.502224 0.406947 0.32425 +0.50253 0.44682 0.285281 +-0.503896 0.194254 0.231752 +0.186953 -0.0411863 0.490407 +0.145072 -0.0518168 0.500903 +0.501756 -0.151225 0.0671023 +0.0052543 -0.411227 0.50829 +-0.42687 0.502769 0.427403 +-0.399293 0.0335716 -0.497648 +0.373542 -0.178454 -0.499307 +-0.350877 -0.498671 -0.226015 +-0.305838 -0.498775 -0.267967 +-0.466944 -0.41676 -0.490746 +-0.0607074 -0.461972 0.478744 +0.0265103 -0.496122 0.43834 +0.00452558 -0.486234 0.442283 +-0.492992 0.454269 0.254991 +-0.0417115 -0.492668 -0.430809 +0.224524 -0.38536 0.514263 +0.509801 -0.389503 0.333439 +0.505753 -0.329988 0.298056 +-0.483658 -0.4176 -0.477988 +0.513105 -0.315617 0.324083 +-0.0400928 -0.484119 -0.454974 +0.499349 -0.289817 -0.289918 +-0.462029 0.373261 0.489278 +0.511527 0.156804 -0.274841 +0.506306 0.16903 -0.318343 +0.498726 0.123596 -0.311225 +0.339213 -0.472117 0.480071 +-0.488139 -0.0281546 0.431955 +-0.123822 0.388926 0.504795 +-0.422322 0.46581 0.480992 +-0.0247886 0.372459 0.509977 +0.202498 0.504568 0.401859 +-0.512223 0.393291 -0.139528 +-0.503695 0.288444 0.288487 +0.504084 -0.358534 -0.0641014 +0.14934 0.511693 -0.33802 +-0.0231953 -0.447344 0.492186 +0.472324 0.468631 -0.46388 +0.257925 0.512374 0.399933 +0.157712 0.504655 -0.411054 +0.27374 0.421058 -0.499531 +0.497623 -0.314575 -0.0931978 +0.426381 -0.402479 -0.489945 +0.367344 0.50576 -0.250396 +-0.254635 0.508535 0.251173 +-0.094979 0.396034 0.499913 +-0.462954 0.45502 0.472835 +0.289207 -0.501984 -0.209939 +0.340901 -0.50896 -0.205421 +0.162469 0.22541 -0.495171 +0.409486 -0.140019 -0.492457 +0.392473 -0.193779 -0.494667 +0.404277 0.488073 -0.453111 +-0.388986 0.512161 -0.0149927 +-0.360274 0.515746 0.0299096 +-0.363924 0.515294 -0.00674807 +-0.14455 -0.436345 -0.488324 +-0.146091 -0.464331 -0.482019 +0.449491 0.260559 0.482528 +0.418898 -0.307593 0.506652 +0.515602 -0.338938 0.32656 +0.408743 -0.500952 -0.441667 +0.43533 -0.4907 0.240278 +-0.00514465 -0.154407 -0.504369 +-0.381585 0.494743 0.397971 +0.369543 0.507509 -0.0302008 +0.239739 -0.50418 0.258457 +0.25381 -0.505855 0.284908 +-0.501421 0.196432 0.350424 +-0.471427 0.425594 0.472887 +-0.497261 0.165609 0.350318 +-0.507518 0.0872906 0.378608 +0.445608 -0.139279 0.495109 +0.411013 -0.493777 -0.417439 +-0.469152 -0.0898625 -0.467219 +-0.293636 0.500543 0.131345 +-0.246744 0.493503 0.443392 +-0.285121 0.50373 0.158506 +-0.468528 -0.0995539 -0.485359 +0.0119437 -0.495839 -0.314349 +-0.251844 0.507526 0.173763 +-0.284691 0.510457 0.187402 +-0.302534 0.496121 0.228242 +-0.413983 0.496111 0.018839 +0.509919 -0.0183066 0.36787 +-0.374461 0.497553 -0.0356652 +0.496584 -0.403334 0.00379057 +0.313308 0.211949 0.511226 +0.502361 -0.413064 0.0383626 +-0.182962 -0.498215 0.39867 +0.230057 0.50216 0.402228 +0.181006 0.494257 0.421738 +0.0271376 -0.195078 0.508375 +0.215072 0.503225 0.10266 +0.182293 0.490186 0.0936463 +0.203538 0.508249 0.0720423 +-0.408315 0.499816 -0.17732 +0.0563687 0.246036 -0.502594 +-0.252408 -0.504561 0.295033 +-0.380365 0.507908 -0.190871 +-0.492131 -0.0614497 -0.265713 +-0.500788 -0.103767 0.0848873 +0.357177 0.505306 0.336561 +0.208847 -0.461889 0.487242 +-0.128141 -0.468051 0.487055 +0.497543 -0.421425 0.182657 +0.256146 0.51062 -0.145954 +0.241939 0.324335 -0.498189 +0.286944 0.309435 -0.516828 +-0.26644 0.468527 0.488852 +0.494125 -0.234207 0.134104 +0.5122 -0.386003 0.366142 +-0.501774 -0.130046 -0.0799782 +0.453006 -0.46723 -0.459487 +0.316636 -0.275021 0.515735 +-0.488693 -0.428797 -0.444323 +-0.480055 -0.239535 0.462453 +0.345278 -0.34105 0.500988 +-0.472795 0.464679 0.136153 +-0.425665 0.50892 -0.321697 +-0.372913 0.503655 -0.287192 +-0.424535 0.503093 -0.29001 +0.486044 -0.444135 0.282957 +0.0857461 -0.493208 -0.0539359 +0.288907 -0.498784 0.168336 +0.384753 -0.498617 0.173914 +0.319573 -0.202119 -0.496462 +0.315474 -0.128165 -0.505158 +-0.139019 0.420837 0.506324 +-0.471768 -0.47667 0.0832677 +-0.378106 0.376974 0.499075 +0.497601 -0.452728 -0.00217184 +-0.485147 -0.174081 0.446002 +-0.500765 -0.0159808 0.252265 +0.440337 0.286117 0.494371 +0.508385 -0.269545 -0.148988 +-0.367916 -0.511547 -0.113539 +0.03935 -0.467519 -0.47538 +0.507638 -0.17366 -0.0883341 +0.50654 -0.219799 -0.0483303 +0.492426 -0.203622 -0.0999509 +-0.456286 0.440407 0.472828 +0.0393584 0.181359 0.500829 +-0.502921 0.440515 0.328435 +0.481233 0.462709 -0.02346 +0.483117 0.229734 -0.465636 +-0.485284 -0.440328 0.413583 +-0.506119 0.426032 0.355104 +-0.490203 -0.45609 0.346159 +-0.489073 -0.443095 0.380854 +-0.218616 -0.477674 0.472993 +-0.258457 0.511105 0.278864 +0.297261 -0.51622 0.32535 +-0.272052 0.461156 -0.491802 +0.449631 -0.482334 -0.329172 +-0.0181114 -0.103445 -0.492373 +-0.429016 -0.509713 -0.369391 +-0.373097 -0.501107 -0.377653 +0.191451 0.508201 -0.287161 +-0.20025 0.505351 -0.0143677 +-0.404218 0.0626899 -0.506762 +-0.00431746 0.51301 0.344117 +-0.412709 -0.487405 0.461012 +-0.216379 0.493066 -0.461911 +-0.414335 -0.494088 0.426005 +0.496956 0.319904 -0.258552 +-0.163356 0.502362 0.0190275 +0.453106 -0.481308 0.223172 +-0.187658 0.497709 0.00772583 +0.500434 -0.12749 0.0610542 +-0.508853 -0.424831 0.400813 +-0.182008 0.500049 -0.0371441 +-0.1855 0.501645 -0.110731 +-0.40424 0.504583 -0.209897 +0.371608 0.50023 -0.19786 +0.370696 0.513989 -0.116868 +0.374489 0.514539 -0.141261 +0.361095 -0.256681 0.50447 +0.206432 0.503001 0.166209 +-0.433008 -0.387758 0.500757 +-0.373222 -0.321006 0.512548 +-0.324706 0.498817 0.0869738 +0.503982 0.356455 -0.215943 +0.495753 0.434852 -0.239915 +0.451783 0.499351 -0.281608 +0.0651562 0.477928 -0.469339 +0.504776 0.407697 -0.1966 +-0.17053 0.507328 -0.00987827 +-0.263464 0.496801 -0.439243 +-0.428221 -0.360008 0.499179 +0.288116 0.506926 -0.209104 +0.244787 0.495483 -0.190977 +-0.281234 0.503267 0.358715 +0.289902 0.497906 -0.181161 +-0.429878 -0.488192 0.0318155 +0.262978 0.502996 -0.171909 +-0.172137 0.475776 -0.466685 +0.317046 0.507372 -0.161868 +0.283996 0.507233 -0.154488 +0.350688 0.51048 -0.269024 +0.397752 0.496321 -0.152538 +0.34428 0.509571 -0.21111 +0.422497 -0.11094 -0.490674 +-0.506866 0.125736 0.230307 +-0.498975 0.182062 0.322472 +-0.501381 0.132725 0.291336 +-0.509704 0.11867 0.323729 +0.282546 -0.499649 -0.269221 +0.506695 0.0711184 -0.234668 +-0.502001 0.0782029 0.30604 +-0.506854 0.131187 0.257863 +0.4987 0.0704676 -0.205719 +0.357805 0.507279 0.0226915 +0.300635 0.496551 0.010996 +-0.509147 0.216759 -0.0294731 +0.500759 -0.0237715 -0.202838 +0.447977 0.477142 0.466179 +-0.255612 0.507224 0.403109 +-0.467366 -0.0121653 -0.477038 +-0.333615 0.494832 0.422918 +-0.297022 -0.455294 -0.498656 +0.46623 -0.469261 0.206296 +-0.189275 -0.498459 0.276589 +-0.496701 -0.296167 -0.0636844 +0.406099 -0.463625 0.479845 +0.171602 -0.500619 0.395124 +0.142807 -0.508995 0.387144 +-0.180709 0.506833 -0.362805 +0.150155 -0.50412 0.442369 +0.462459 0.4809 0.428147 +0.147421 -0.494987 0.41233 +0.498584 0.0340337 -0.357604 +0.497051 0.19377 -0.316238 +-0.0342101 0.458281 0.484547 +-0.0561821 0.426761 0.490039 +0.250053 -0.497646 -0.0689441 +-0.0304405 0.419659 0.506834 +-0.506421 -0.22459 -0.174437 +0.507438 0.243455 0.334438 +-0.500063 -0.155457 -0.0645615 +-0.480959 0.219403 0.458728 +-0.242872 0.497658 0.0174272 +-0.221367 0.510154 0.0388278 +0.337316 0.377414 -0.514176 +0.272915 0.373545 -0.50691 +-0.507785 -0.0535461 0.168348 +0.321471 -0.165828 0.500673 +-0.193894 0.479666 0.457011 +0.293709 -0.158517 0.502175 +-0.270846 0.51302 0.332394 +-0.0300122 -0.399485 -0.496056 +0.141008 0.0342044 0.497617 +0.283023 0.512872 0.396532 +0.300613 0.507181 0.379408 +0.340875 0.506411 0.409722 +0.121881 0.492344 0.0132412 +0.341449 0.509857 0.0642477 +0.169458 0.496152 0.229071 +-0.509846 0.38768 -0.381525 +0.133807 0.213278 -0.504089 +0.273306 -0.178896 0.505626 +0.265556 -0.0368796 0.508436 +0.135739 0.360132 0.513072 +0.505956 0.0100999 0.178641 +0.492769 -0.00974011 0.196773 +0.509262 0.0166126 0.236874 +0.493565 0.0620269 0.232034 +0.507987 -0.0115679 0.222418 +0.22298 -0.129951 -0.503856 +0.274195 -0.193178 -0.505439 +-0.310473 0.50267 0.0636372 +-0.479719 0.452707 -0.470718 +-0.459552 -0.49464 0.109085 +-0.395299 0.502249 0.0387489 +0.282917 -0.235781 -0.507803 +0.312023 -0.230173 -0.504205 +0.247529 -0.203311 -0.496791 +0.0622902 0.492197 0.246581 +0.041943 0.503683 0.296278 +0.504545 -0.113662 -0.175737 +0.0490741 0.51133 0.361336 +-0.0147748 0.506574 0.293257 +-0.497744 -0.308587 -0.16352 +0.396245 -0.503117 0.433584 +-0.496821 -0.321193 -0.112991 +-0.17573 0.503738 -0.0857785 +0.150425 -0.0770493 0.50544 +0.205123 -0.149226 0.506672 +0.459024 -0.492612 -0.425777 +0.238967 -0.0946248 0.500078 +0.182513 -0.121035 0.501111 +0.505594 0.130073 0.270391 +0.495691 0.197753 0.157568 +0.499363 0.157178 0.1849 +0.499064 0.103266 0.173214 +0.44044 -0.283469 -0.496459 +0.297414 -0.50673 -0.324012 +0.363012 0.507856 -0.0926183 +0.102417 0.496009 0.110646 +0.490717 -0.380784 -0.436041 +-0.477149 0.466317 -0.307348 +0.142218 0.504371 0.0317238 +0.133548 -0.489473 -0.1949 +0.458532 0.0297856 0.481583 +0.123913 0.107993 0.491763 +0.148943 0.503384 0.0906998 +-0.451702 -0.0942301 -0.494535 +-0.399945 -0.504875 0.302023 +-0.367728 -0.51221 0.242782 +-0.386963 0.500101 0.266526 +0.430114 -0.463064 0.473302 +-0.417426 0.502183 0.233761 +-0.395574 0.512506 0.238697 +0.478165 -0.321315 0.473323 +-0.5047 0.377873 0.328981 +-0.339868 -0.0789402 -0.495865 +0.288847 0.494588 -0.0132231 +0.334905 0.495703 -0.087865 +0.394902 -0.452001 0.501301 +0.124524 -0.490994 0.0743251 +0.348833 -0.401926 0.506697 +0.127712 -0.499608 0.0100276 +0.0636833 -0.50505 -0.0301875 +-0.456618 -0.265338 0.496385 +-0.210446 0.267062 0.512434 +0.362352 0.502425 0.253123 +-0.459531 0.422147 -0.478317 +-0.384893 -0.497587 0.429525 +0.509838 0.411884 0.0764504 +0.501856 0.427732 0.0534419 +-0.30273 0.486343 0.465092 +-0.484438 0.396385 -0.451311 +0.497618 0.0463585 -0.0858221 +0.20346 0.498216 -0.435441 +-0.448397 -0.493884 0.353292 +-0.448857 -0.47192 -0.473094 +0.187447 -0.494631 0.205457 +0.47172 -0.274098 -0.471854 +0.244125 0.515921 0.349255 +0.250035 0.51549 0.281442 +0.313895 0.471427 -0.478636 +0.0375401 0.492426 0.195923 +0.0645738 0.501291 0.195647 +-0.372875 0.455405 -0.490043 +0.12759 0.4995 -0.0311487 +0.198527 0.506301 -0.0399881 +0.203731 0.500717 0.01175 +0.160987 0.501402 -0.0353498 +0.500167 -0.246817 0.454424 +0.00294497 0.498942 0.0974771 +0.0212264 0.50351 0.0561875 +0.0541926 0.497232 0.415234 +0.146514 0.508691 -0.00238218 +0.327335 0.436208 0.49838 +0.500162 -0.257576 -0.277529 +0.325143 0.400862 0.517095 +0.165067 0.502727 0.118908 +-0.486522 0.455344 0.435007 +0.481253 0.196334 0.457866 +0.196484 0.502067 0.203323 +0.498263 -0.158461 -0.387417 +0.148184 0.513444 -0.382392 +-0.325638 -0.495824 0.456082 +-0.38035 0.326679 -0.51008 +-0.265712 0.0855356 0.499781 +-0.384878 0.477835 -0.46499 +0.361971 0.295292 -0.50107 +0.315034 0.320942 -0.512199 +0.343832 0.269973 -0.508319 +0.491866 0.229046 -0.215203 +0.505085 0.209386 -0.26402 +0.491282 0.144393 -0.224327 +-0.0258535 0.497926 0.390139 +-0.496188 -0.277107 -0.425956 +0.503087 0.203317 0.242416 +-0.341789 -0.477166 -0.478339 +-0.460072 -0.379455 0.47724 +0.495792 0.167756 0.297169 +-0.49635 -0.224729 0.0403641 +0.513164 0.179549 0.325327 +-0.164005 0.488932 0.462492 +0.174488 0.509166 -0.212356 +0.410987 0.475657 0.465164 +0.272814 0.296475 0.507362 +-0.143993 0.502981 0.378692 +-0.477371 0.473178 0.403198 +-0.0639025 0.505763 0.371145 +0.0195798 0.212657 -0.491429 +-0.491772 -0.0583722 0.12509 +-0.190793 0.508514 0.423421 +-0.152862 0.497313 0.448078 +0.486442 0.451007 0.0584501 +-0.451119 0.495129 -0.0175683 +-0.413017 0.239715 0.499426 +-0.431551 0.212071 0.506405 +-0.352368 -0.446346 0.487961 +-0.289093 -0.34144 0.51139 +-0.157326 0.50866 0.154308 +-0.18944 0.505434 0.116076 +-0.197602 0.492219 0.141617 +0.453141 0.476293 -0.415691 +0.276892 0.501006 -0.132016 +0.193912 0.493629 -0.130731 +0.240106 0.49481 -0.0826624 +-0.50593 0.275697 0.00970348 +0.22662 0.505645 -0.137285 +0.294878 0.516654 0.35219 +0.346031 0.513471 0.306877 +0.0101134 0.510218 -0.282797 +-0.195001 0.497478 0.316028 +0.466109 0.483099 -0.299109 +-0.0798258 0.504333 0.38749 +-0.484654 -0.32994 0.449568 +-0.177175 0.514644 0.372513 +0.241477 0.304196 0.515461 +-0.0663452 -0.47792 -0.468105 +0.0693782 -0.499708 -0.135453 +0.286308 0.234406 0.50388 +-0.199841 0.500741 0.0626043 +-0.291158 0.406566 -0.506206 +-0.502602 0.358947 -0.212983 +0.171184 -0.475106 0.463633 +-0.510331 -0.39916 0.414645 +-0.4968 0.280011 -0.263554 +0.500315 -0.0401007 0.201916 +-0.514377 0.344538 -0.270326 +-0.503235 0.306235 -0.316449 +-0.0137773 -0.493445 -0.416887 +-0.27663 0.513118 -0.272578 +0.468104 0.147417 0.465239 +-0.36894 -0.500543 -0.0836979 +0.114867 -0.22968 -0.507603 +-0.028911 -0.234483 -0.5002 +-0.201144 0.499325 0.162666 +0.0769541 0.367444 0.496377 +0.297947 -0.495801 -0.136451 +0.0211177 0.395053 0.499881 +0.0773645 0.427716 0.507109 +0.0968769 0.508897 -0.413893 +0.013074 0.495481 0.280106 +-0.246311 -0.306673 0.497569 +-0.502436 0.0026872 0.393373 +-0.489541 0.0276592 0.452733 +-0.494307 0.0686956 0.403675 +-0.495144 0.00762588 0.425385 +0.0370899 0.506346 -0.3291 +0.408993 0.505092 0.0874199 +0.043174 0.508027 0.0696624 +-0.391222 -0.417204 0.49435 +-0.280841 0.496796 0.238517 +-0.171157 0.500298 0.202618 +0.0464248 0.501878 -0.394059 +0.477518 -0.299415 -0.468173 +0.0690825 0.505002 -0.374758 +0.504628 0.359151 -0.162763 +-0.0186701 0.512466 -0.355823 +0.273009 -0.498025 -0.162622 +-0.100074 0.509267 -0.377049 +-0.153945 0.513192 -0.401831 +-0.161874 0.497949 -0.378152 +0.507502 -0.0578524 -0.280809 +0.496787 -0.0265715 -0.249213 +0.510731 -0.0506154 -0.253202 +-0.433966 0.296429 -0.495013 +-0.499588 -0.447318 0.242577 +0.0414562 0.224272 -0.490761 +0.0781772 0.496406 0.117317 +-0.0532357 -0.282731 0.493627 +-0.462471 -0.468005 -0.482283 +0.238247 0.494706 0.155434 +0.250338 0.494174 0.0700667 +-0.123402 0.495648 0.354155 +-0.0577622 0.508446 0.34925 +0.511941 -0.401017 -0.369306 +0.233467 0.42911 0.492608 +0.495304 -0.0775247 0.391431 +-0.339612 0.447717 0.491565 +-0.0371095 0.509773 0.303277 +-0.0310144 0.514498 0.345964 +0.00601445 0.503246 0.364752 +-0.343784 -0.035806 0.514649 +-0.464365 0.482198 0.20142 +-0.377898 -0.512044 -0.233937 +-0.33932 0.243949 -0.503104 +0.00648562 0.496195 -0.460785 +-0.500247 -0.370676 -0.204224 +-0.496607 -0.388828 -0.0755491 +-0.503542 0.290892 -0.358448 +0.0536739 0.508837 0.0955874 +0.00976212 0.132244 0.491571 +0.0498975 0.497059 0.155481 +0.348075 0.509302 0.154288 +0.298679 0.502973 0.227203 +0.270255 0.498743 0.113272 +0.48905 0.291568 0.471666 +0.324874 0.49778 0.173746 +0.164898 -0.363464 -0.503066 +0.382157 -0.04639 0.500203 +0.056468 -0.0377234 0.493463 +0.36066 -0.0597862 0.501305 +0.502852 0.293961 -0.0273039 +0.00953829 -0.249815 0.498854 +0.497867 0.247583 -0.0999725 +0.492301 0.205324 -0.0106 +0.183672 0.321121 -0.496549 +0.3817 0.0366697 -0.504367 +0.146959 0.378781 -0.496989 +0.501873 -0.156456 -0.286688 +-0.402396 -0.30975 -0.50207 +-0.303062 -0.298081 -0.499459 +-0.200661 0.453336 0.500455 +-0.380348 -0.22505 -0.500084 +-0.351388 -0.276866 -0.50922 +0.158365 0.504097 0.408969 +0.0254122 0.502559 0.402698 +0.0924389 -0.502416 -0.259418 +0.106305 0.509239 0.404768 +0.329768 -0.511129 0.282425 +-0.141038 0.508257 0.279409 +-0.162495 0.508146 0.256344 +0.212275 -0.30269 -0.509324 +0.172227 -0.385814 -0.498753 +0.500168 -0.148118 -0.106343 +-0.491936 0.0218774 0.140688 +0.20839 -0.336282 -0.506631 +-0.347976 0.50593 0.399743 +0.0917157 0.496905 0.256608 +-0.286711 0.182096 -0.511368 +-0.364076 0.165197 -0.511227 +0.226996 -0.396482 -0.504335 +-0.317015 0.125541 -0.498638 +0.495222 0.0861306 0.229022 +-0.208964 -0.269337 -0.508894 +-0.236717 -0.172889 -0.501914 +0.403355 0.500299 0.0258203 +-0.291449 -0.197168 -0.511951 +0.470961 -0.441742 0.460297 +0.172566 -0.462119 -0.483128 +-0.42982 0.496433 0.109883 +-0.376121 0.502525 0.0635911 +0.451355 -0.315213 -0.496287 +-0.342112 0.500035 0.0624354 +-0.382038 0.507186 0.118045 +-0.228466 0.0417364 -0.493599 +-0.281163 0.0404838 -0.509705 +-0.24574 0.0841367 -0.493531 +-0.398299 -0.0861257 -0.5066 +0.11579 0.31023 -0.508026 +0.109682 0.256271 -0.506814 +0.134664 0.271001 -0.501548 +-0.0941418 0.371567 0.506717 +-0.187199 0.505396 -0.393017 +-0.245233 0.50676 -0.412747 +-0.381134 0.498384 0.295277 +0.400396 -0.168839 -0.505698 +0.323488 0.12629 -0.499005 +0.140087 0.502663 0.219253 +0.508927 -0.164258 0.232407 +0.494913 -0.218783 0.240563 +0.498623 -0.229568 0.16483 +0.478386 0.444807 -0.464057 +0.500631 -0.265175 0.210347 +0.50584 -0.127366 0.299111 +-0.163797 0.492825 -0.0599625 +0.509652 -0.212308 0.216758 +0.514555 -0.141949 -0.343945 +0.34252 -0.148107 0.496182 +0.297068 -0.0318658 0.512728 +0.329591 -0.0266144 0.503406 +-0.468521 -0.477941 -0.207344 +0.353339 -0.0101545 0.501693 +0.336466 -0.0966954 0.495076 +-0.485597 -0.441765 0.459809 +0.511134 -0.419041 0.321314 +0.469924 0.466085 -0.21832 +0.499033 -0.0186701 0.429594 +-0.48063 0.445404 -0.430155 +0.221989 -0.508144 -0.192422 +-0.287778 -0.22449 -0.500086 +0.198882 0.296175 -0.511498 +-0.101505 -0.423734 0.496893 +-0.225145 0.187279 0.508253 +0.0498629 -0.498281 -0.149096 +-0.487133 -0.432765 -0.0418141 +-0.0940867 -0.224705 -0.490453 +0.495748 0.283477 -0.224003 +-0.497057 -0.195524 0.216318 +-0.108986 0.165118 0.501928 +-0.306396 -0.499918 -0.328504 +-0.00360174 0.381196 0.505182 +-0.218499 0.156212 -0.490263 +-0.00275746 0.498902 -0.244051 +-0.507521 -0.234964 0.145906 +-0.495267 0.451879 -0.346432 +0.497513 0.433863 -0.212485 +-0.504817 -0.186529 -0.141232 +-0.509632 -0.362339 -0.270527 +-0.506036 -0.413019 -0.281883 +0.513101 0.281537 0.339932 +-0.491927 -0.416306 -0.250855 +0.0206377 -0.472833 -0.464122 +-0.397307 0.0399289 0.495649 +-0.102514 0.278334 -0.49441 +0.164084 -0.506387 0.193043 +-0.485684 0.440468 -0.268306 +0.187655 0.475832 0.4634 +0.307731 -0.490378 -0.453152 +0.0302884 -0.372656 0.498082 +-0.363621 -0.355171 -0.503772 +0.510188 0.223687 0.359661 +-0.438321 -0.488392 -0.338461 +0.185187 -0.500083 -0.429444 +0.503678 -0.397664 -0.202856 +-0.428263 0.499614 -0.200189 +0.100517 -0.506914 0.285131 +0.0849431 -0.36439 0.507632 +-0.0529538 0.500881 -0.154072 +-0.39144 -0.494411 0.18979 +-0.198947 0.0425899 -0.494693 +-0.504338 -0.0979401 0.267629 +-0.0133474 0.501834 -0.266163 +0.331071 0.0266823 -0.500419 +-0.202863 0.371316 -0.495743 +0.488471 -0.434906 0.438213 +0.365888 0.179268 0.514526 +0.0111217 0.164975 0.501397 +0.298979 -0.495497 0.0609964 +-0.500953 -0.213967 0.101018 +0.49469 0.141508 0.023263 +-0.260044 -0.457806 0.496668 +-0.505849 -0.0512462 -0.398887 +0.440882 -0.494864 0.38067 +-0.225539 -0.510051 0.426074 +-0.506583 0.0072157 -0.271095 +-0.495682 -0.02554 -0.233815 +-0.483782 -0.254262 0.44253 +-0.495282 0.0504924 -0.372052 +-0.502659 0.0340123 -0.10179 +0.0372581 -0.497699 -0.315951 +0.12254 0.180852 0.493781 +0.506278 -0.290706 0.338246 +0.0365262 0.245963 0.49565 +0.513187 -0.18179 0.355667 +0.101535 0.413806 -0.510187 +-0.335019 0.209592 -0.510156 +-0.178438 -0.506433 -0.373885 +0.501249 0.179384 0.213352 +0.344863 -0.132476 -0.499643 +0.14734 -0.501027 0.0232311 +0.237986 -0.511 -0.396493 +0.344747 0.122981 -0.512515 +0.3393 -0.496518 0.148611 +-0.495588 0.0898529 0.326544 +-0.0305178 0.441205 -0.503406 +0.212696 0.26559 -0.500801 +0.503862 -0.441664 0.227748 +-0.2727 -0.501263 -0.138303 +-0.50279 0.18248 0.264116 +-0.327211 -0.228159 -0.506147 +0.503491 -0.0968016 0.142993 +-0.333335 0.50378 -0.185214 +-0.103843 -0.492408 0.214597 +-0.495139 0.0803329 0.282068 +-0.475046 0.467258 -0.221602 +0.507367 0.233784 0.0363977 +-0.354313 0.503664 -0.144358 +0.363506 -0.455089 -0.485911 +-0.509626 -0.24866 0.227038 +-0.446445 -0.48194 0.403026 +0.435344 0.0696889 -0.495621 +-0.388717 0.495661 0.192499 +0.492774 -0.428974 -0.187122 +-0.231778 -0.273404 0.508022 +-0.362878 -0.38441 0.517666 +-0.0645739 -0.500863 -0.390441 +-0.0409399 -0.500174 -0.405791 +0.504741 0.374679 0.00127603 +-0.475341 -0.195774 0.482263 +0.103176 0.438265 0.497619 +-0.115517 0.30555 -0.494163 +0.0230881 0.361821 0.509014 +-0.0805336 0.362061 -0.504914 +-0.499053 0.292494 -0.38832 +0.152316 0.331122 0.509289 +0.498297 -0.42364 -0.410556 +0.499819 0.422169 -0.266945 +0.427079 -0.503197 -0.168507 +-0.348346 0.512373 0.21351 +0.346671 0.498077 -0.392384 +-0.296111 -0.403369 0.501253 +0.286199 0.349567 0.510667 +-0.367354 0.0415977 0.503437 +-0.361055 -0.502004 -0.146068 +-0.397806 -0.507443 -0.0127066 +-0.367915 -0.509902 -0.178009 +0.496995 0.286553 -0.061201 +-0.413411 -0.493922 0.257234 +-0.434095 -0.489806 0.32555 +-0.490685 0.0140712 0.0785156 +-0.459943 -0.469837 0.448576 +-0.210632 -0.507202 -0.357466 +-0.442877 0.487347 -0.193067 +0.0321241 0.435322 0.497686 +0.167118 -0.182808 -0.493765 +0.364171 -0.471699 0.470885 +0.0193631 -0.252363 -0.507902 +0.146394 -0.169999 0.501085 +-0.0390409 -0.354129 -0.505319 +0.399199 -0.280883 -0.510924 +0.468684 -0.471295 0.262271 +0.418476 -0.267794 -0.504251 +-0.210616 -0.502595 -0.32476 +0.436958 -0.247743 -0.502208 +0.208846 0.232909 -0.50387 +-0.151523 0.441172 0.486469 +0.495676 0.279778 -0.0918026 +-0.498408 0.369849 -0.180038 +-0.167235 -0.189379 -0.504842 +-0.445055 -0.483241 0.29983 +-0.241518 0.494894 -0.120821 +-0.328039 0.515711 -0.159716 +-0.285964 -0.103485 -0.50451 +0.279235 0.509095 0.28833 +-0.313739 -0.506944 -0.360441 +-0.31865 0.42925 -0.495245 +0.343546 0.0767568 -0.501463 +0.423983 -0.462554 -0.481141 +-0.465003 -0.459057 0.466284 +0.396767 -0.308375 -0.506287 +0.477221 -0.466283 0.444109 +0.463928 -0.458165 -0.468584 +-0.508082 0.185104 -0.0864894 +-0.347202 0.307819 0.513286 +0.424773 -0.449863 0.498792 +0.497305 -0.394282 0.261557 +0.135221 0.505056 0.19581 +-0.209156 0.30186 -0.510497 +-0.455643 -0.480922 0.462918 +0.495184 0.183085 -0.19647 +0.373236 -0.505422 -0.079917 +0.515528 0.401547 -0.386689 +0.506977 0.419224 0.10434 +0.0613206 -0.223044 -0.506859 +0.126707 0.505115 -0.426765 +0.0762691 -0.128072 -0.498728 +-0.310992 -0.386104 -0.515631 +-0.503514 0.446753 0.278094 +0.378044 -0.50695 0.122365 +0.147765 -0.507555 -0.389442 +-0.352086 -0.241827 -0.514478 +0.451058 -0.485562 0.457893 +0.212751 0.229314 0.504018 +-0.503508 0.303378 -0.0672984 +-0.369117 -0.503977 0.40154 +0.473085 -0.208957 0.488622 +-0.392059 -0.0139122 0.509416 +-0.482982 0.469182 -0.131969 +-0.45381 -0.208363 0.489069 +-0.444976 -0.0231334 0.483915 +0.492553 0.114719 -0.02684 +-0.40771 -0.205256 0.494659 +0.502369 -0.194864 0.160691 +0.491034 -0.187564 0.13408 +-0.00779999 -0.430207 0.505619 +0.497167 -0.442171 0.311094 +0.483948 -0.405332 0.456167 +0.508197 -0.13388 -0.372226 +0.499657 0.133699 0.400952 +-0.509328 0.0157067 -0.161922 +0.211529 0.515047 -0.335893 +-0.51086 0.292747 -0.419696 +0.2903 0.464572 -0.494615 +0.287429 0.399127 -0.510636 +-0.506592 0.404739 0.149028 +-0.400752 -0.252204 -0.508715 +-0.494068 -0.15215 -0.212992 +-0.186935 -0.153036 -0.500567 +-0.0421754 -0.502144 -0.173896 +0.514818 0.37037 -0.382466 +0.503318 0.365879 -0.327389 +0.357438 0.163174 -0.506128 +0.174869 -0.339649 -0.508541 +0.461272 -0.100458 0.495123 +-0.200113 0.238105 -0.491955 +0.298029 0.494471 0.0740874 +0.50809 -0.250173 -0.167415 +-0.507286 0.243902 0.00243096 +0.405513 0.511341 0.358286 +0.382388 0.506225 0.339037 +0.0793727 -0.51296 0.307419 +0.389709 0.514676 0.390012 +-0.224698 0.501281 -0.143242 +0.458108 -0.487282 0.418787 +-0.492628 -0.157219 0.254006 +0.187353 -0.267797 -0.500307 +0.37104 0.0501823 0.498414 +-0.471834 -0.471417 0.172348 +0.41906 0.490006 -0.132589 +0.506433 -0.377438 -0.413634 +-0.494306 -0.417666 -0.425285 +-0.252002 -0.0620567 0.511714 +0.0111294 -0.504355 -0.368969 +0.49589 0.419622 0.255079 +0.0359285 0.31039 0.509275 +-0.500957 -0.379758 -0.320638 +0.423145 0.512051 -0.372027 +0.508342 -0.0788573 0.0844771 +-0.465892 0.485995 -0.199576 +0.473576 -0.479409 -0.374789 +0.303771 0.0350201 -0.509415 +0.151705 -0.50747 -0.0478194 +0.495207 0.279609 0.150951 +0.407703 0.489204 0.447406 +0.510575 -0.338538 0.192907 +0.299106 0.416532 -0.496561 +-0.506777 0.402682 -0.35611 +-0.469147 0.482603 -0.352501 +0.514764 0.292075 -0.403507 +-0.444999 0.490728 -0.216265 +0.296232 0.187674 0.513306 +-0.390683 0.187134 -0.513827 +-0.145212 0.304066 -0.500425 +0.505339 0.329732 -0.101755 +-0.505458 -0.0422009 0.333608 +-0.113612 -0.414335 -0.499679 +0.371536 0.511861 0.415189 +-0.181944 0.0384196 0.503188 +-0.215278 0.0783977 0.50367 +-0.38568 -0.342851 0.519744 +-0.146753 -0.370127 -0.499877 +0.365705 -0.0323481 -0.51504 +-0.387866 0.507136 -0.431615 +0.227127 0.214463 -0.505325 +-0.0886474 -0.304194 -0.497937 +-0.511375 0.366552 -0.247113 +-0.512299 0.180271 0.377313 +0.498213 0.223493 -0.283102 +-0.481501 -0.377247 0.474109 +-0.272274 -0.249902 -0.50556 +0.487564 0.310429 -0.474609 +-0.417566 0.477649 0.47252 +0.498622 0.160412 -0.203607 +0.485757 0.140201 0.429544 +-0.511474 -0.303673 0.0770031 +-0.0937347 0.250493 -0.495245 +-0.0250963 -0.133705 -0.493361 +-0.49643 -0.428635 -0.408221 +-0.492286 -0.132515 0.459951 +-0.49975 0.23846 -0.346075 +0.504479 0.0671516 0.11282 +0.416133 0.354361 0.508527 +0.366589 -0.500979 0.365652 +0.280239 0.126215 0.494224 +-0.50125 -0.339846 -0.0906265 +-0.0837607 -0.505458 0.310058 +-0.473517 -0.471853 -0.0272395 +0.500236 -0.387258 -0.0196445 +0.335195 0.480095 0.462165 +0.47778 -0.169788 0.461059 +-0.115227 -0.296888 -0.497468 +0.477824 0.45413 0.461236 +-0.414352 -0.0110239 -0.49436 +0.478658 0.0806272 -0.458416 +0.466988 -0.475221 -0.311908 +-0.418187 0.0133188 -0.498307 +-0.515665 -0.247182 0.367674 +0.415214 -0.473512 0.464218 +0.505165 -0.281079 0.124348 +-0.435939 -0.440692 0.489893 +-0.360015 -0.512281 0.314238 +-0.425432 -0.500942 0.351642 +0.18996 0.0110591 0.490883 +-0.496783 0.390571 -0.19955 +-0.505034 0.39499 -0.255476 +0.480105 -0.477015 -0.197838 +0.498975 0.411081 -0.412055 +0.273212 0.0439031 0.505311 +-0.16502 0.100319 -0.495673 +0.493819 0.261275 0.0491242 +0.514266 -0.377157 -0.291786 +0.496674 0.381661 0.0729321 +-0.507905 0.204686 0.0330154 +-0.23674 -0.0878351 -0.508966 +0.0214083 -0.494741 0.237633 +0.441876 -0.403162 0.488088 +-0.500637 0.169411 -0.422205 +-0.507582 -0.397214 -0.102826 +-0.501832 0.291938 -0.0204214 +-0.506914 0.0886772 -0.270407 +-0.350869 0.417663 -0.509438 +-0.504628 0.116263 -0.263841 +-0.494695 0.166816 -0.060863 +-0.181163 -0.509327 -0.0277289 +0.479408 -0.147141 0.480182 +-0.504729 0.315917 0.0610726 +0.249819 -0.49857 0.0397109 +-0.504276 -0.433805 -0.304427 +0.451562 0.494517 -0.343354 +0.502408 0.0630251 -0.443068 +0.411037 -0.501154 -0.0881569 +-0.50002 -0.334891 -0.420057 +-0.502594 0.104037 -0.393175 +0.231387 -0.178143 -0.499026 +0.0683292 0.497366 0.0674435 +-0.465913 0.173466 -0.494395 +-0.504045 0.410335 0.29455 +-0.402672 0.505422 -0.403997 +0.500933 0.42946 -0.391255 +0.509781 0.328942 -0.211049 +0.472101 0.484761 -0.134413 +0.266636 0.504998 -0.308757 +0.06204 0.481263 0.471436 +-0.490613 0.423657 -0.456816 +0.28012 -0.171877 -0.497558 +-0.29164 0.479257 -0.484277 +0.491692 -0.4634 0.218578 +0.512085 -0.401461 -0.338365 +0.512258 -0.340783 -0.368482 +0.0300879 -0.498593 -0.268662 +-0.39423 -0.504329 0.0214806 +-0.388116 -0.503689 -0.0406833 +-0.290064 -0.430576 -0.508843 +-0.355311 -0.510883 0.191174 +-0.378826 -0.504173 0.134091 +-0.372976 0.497846 -0.453912 +0.10404 0.49974 0.322178 +0.508479 -0.265465 -0.120965 +0.0195858 -0.404863 -0.504759 +-0.386588 -0.507348 -0.431272 +0.271929 0.507989 -0.085948 +0.159993 0.489621 -0.124446 +0.466173 0.095209 -0.471946 +-0.260366 -0.336395 -0.501503 +0.473795 -0.469624 -0.430335 +0.380667 0.505356 -0.0770955 +0.282426 -0.206496 0.495277 +0.513134 -0.37185 0.000685296 +0.49996 -0.104919 -0.379648 +0.389257 -0.51169 -0.379204 +-0.490358 0.253857 -0.464004 +-0.48883 -0.137061 -0.42867 +0.176391 0.494718 0.393735 +-0.180881 -0.454933 0.485289 +0.501537 -0.435916 -0.12079 +0.49476 0.421763 -0.433359 +-0.50168 -0.163926 0.369173 +0.502751 0.0960074 -0.102148 +-0.462518 -0.205202 -0.472776 +-0.00798212 0.325479 -0.513649 +0.499085 0.435688 -0.454762 +0.508991 -0.37459 -0.260899 +0.418455 -0.349516 -0.50508 +-0.457157 0.262195 0.498771 +-0.471265 0.151845 -0.477389 +-0.514696 0.366465 0.409888 +-0.00186652 0.496069 0.446862 +0.453686 0.459545 -0.480028 +-0.327844 0.455091 -0.49614 +0.501208 -0.0919546 -0.403237 +-0.461459 -0.483837 -0.122548 +0.266748 -0.502411 -0.0467151 +0.323164 0.50789 0.334437 +-0.391514 -0.507174 -0.130717 +-0.489871 0.156957 -0.466362 +0.368171 0.318216 0.517015 +0.498573 -0.0703153 -0.308179 +0.434988 0.257777 0.506284 +-0.230323 -0.505497 -0.181476 +-0.243199 -0.502003 -0.234931 +0.176278 -0.500721 0.057259 +-0.374178 0.147557 0.501466 +0.501934 0.0464618 -0.251483 +-0.368373 0.491041 0.463322 +-0.115743 0.502907 -0.0827505 +0.404502 0.494896 0.418589 +-0.330741 -0.1456 -0.513909 +0.452762 -0.288318 0.482162 +-0.380936 -0.113326 -0.513071 +-0.491787 0.218424 -0.180356 +0.355233 -0.517461 0.397465 +0.515515 -0.203087 0.343295 +-0.505298 -0.223791 -0.0277568 +0.446745 0.491436 0.0744828 +-0.489814 -0.184337 0.467345 +-0.485341 -0.0284347 -0.44367 +-0.497276 -0.424478 -0.384421 +-0.465956 0.247198 -0.490956 +-0.508228 0.00371574 -0.412436 +-0.434639 0.452877 -0.474401 +0.464368 -0.471828 0.151966 +0.32352 -0.480585 -0.467079 +0.163715 0.383962 0.506221 +0.447146 -0.452435 0.480275 +0.465858 0.147033 -0.47185 +-0.349655 -0.502801 0.0719813 +-0.340999 -0.401551 0.504008 +-0.130932 0.499037 0.409587 +-0.437693 -0.486648 0.426097 +-0.496143 -0.131909 -0.383794 +-0.413956 -0.51011 -0.307036 +0.50534 -0.120072 0.218491 +-0.236496 -0.436203 -0.492822 +-0.488965 0.211203 -0.451433 +-0.18117 -0.493828 0.441258 +-0.199961 -0.493297 -0.255851 +0.428901 0.00112216 -0.499417 +-0.319413 -0.435785 -0.496903 +0.500351 0.353197 -0.285547 +0.0734708 0.466249 -0.484247 +0.466936 0.479693 0.256785 +0.208764 -0.493715 0.256206 +0.173038 -0.345503 0.504645 +-0.0681916 -0.498183 -0.312387 +-0.132523 0.229196 0.50041 +0.475863 -0.466146 -0.228031 +-0.450166 0.39958 0.486112 +0.386195 -0.442114 -0.502107 +-0.308542 0.49734 0.297313 +-0.256999 0.493935 0.135353 +-0.513335 0.415587 -0.335032 +-0.483502 0.446161 -0.297683 +-0.374276 -0.481446 0.468385 +-0.363254 0.485118 -0.466968 +-0.398891 0.499393 0.423935 +0.487161 -0.459009 0.303582 +-0.365452 -0.501771 -0.448853 +-0.482124 -0.474368 0.372616 +0.511151 -0.0392445 -0.394216 +-0.422436 0.49296 -0.258754 +-0.26171 -0.435765 0.5053 +0.103814 -0.501156 0.00681238 +0.420475 0.34861 -0.511894 +0.444127 0.394543 -0.488279 +0.510829 0.30784 0.0716353 +-0.450784 -0.300277 -0.48993 +-0.388365 -0.439504 -0.494201 +0.491721 0.0984524 -0.44459 +-0.497955 0.198731 0.445849 +-0.149409 -0.483683 0.459572 +-0.229711 -0.512739 -0.257458 +-0.462914 0.281842 0.476988 +-0.508169 -0.353459 -0.329348 +0.479418 -0.410131 -0.468355 +-0.502279 0.35609 -0.116995 +-0.514018 0.370586 0.014553 +-0.244555 0.288141 -0.511779 +0.0749224 0.365342 -0.50857 +-0.511463 -0.149686 -0.36798 +0.00431463 -0.506769 0.0408487 +-0.347434 0.466619 -0.491751 +-0.512701 0.347301 0.260089 +-0.510297 -0.399648 0.0807242 +0.432009 0.0676442 0.491882 +0.410479 0.195663 0.497687 +0.501664 0.113992 -0.377647 +-0.439466 -0.162801 0.500123 +0.493443 0.0589056 -0.407526 +0.43368 -0.333839 -0.494615 +0.467692 -0.176131 0.482586 +0.493157 -0.140987 0.173461 +-0.0058322 0.225706 -0.509526 +-0.494004 0.231996 -0.10155 +0.0427216 0.40018 -0.495028 +-0.497597 0.127382 -0.384746 +-0.453602 -0.480338 0.329866 +-0.47115 -0.464738 0.456041 +0.159231 -0.23381 0.498758 +0.499459 0.204517 0.023014 +-0.11687 0.490985 -0.172199 +0.0158808 -0.505371 -0.0604319 +0.507422 -0.273803 -0.367874 +0.48966 -0.0861268 0.442202 +-0.469624 0.469494 0.0787668 +0.280913 -0.511087 0.138614 +0.501504 0.425542 0.196907 +0.409117 -0.083179 -0.493632 +-0.475446 0.229005 0.482513 +0.364802 -0.108436 -0.500573 +0.3109 -0.488346 0.475056 +-0.500932 -0.18443 0.140996 +-0.424486 0.440432 -0.482295 +0.501756 0.130626 0.166368 +-0.461307 -0.480814 0.42866 +-0.463736 -0.482343 0.354514 +0.142226 -0.202848 -0.507006 +0.276718 0.379465 0.514012 +-0.476711 -0.460135 -0.191702 +-0.506817 -0.439884 0.112559 +-0.389805 0.123111 -0.512937 +-0.490815 0.327307 0.46556 +-0.43468 -0.473311 0.459911 +-0.380494 0.0761943 -0.512107 +-0.160825 0.460858 -0.498413 +0.436983 -0.491603 0.271533 +0.305122 0.493488 -0.0364003 +0.36717 -0.454167 0.504173 +0.275849 0.50533 0.00671648 +0.499898 0.0732856 0.253708 +0.503266 0.0687019 0.304515 +0.283392 -0.468161 -0.48759 +-0.372218 -0.431793 0.494524 +-0.030892 0.392728 -0.511859 +-0.373675 0.499269 -0.319796 +-0.42055 0.500477 -0.351354 +0.359495 -0.109902 0.511396 +0.503332 -0.232346 -0.18837 +-0.459036 0.487305 -0.150849 +0.462804 -0.388325 0.488891 +-0.411242 -0.457244 0.496036 +-0.113608 0.447509 -0.493496 +0.445671 -0.19625 0.484638 +-0.144595 0.417805 -0.493182 +0.0708087 -0.496567 -0.373052 +-0.361194 0.507759 -0.0637033 +-0.25529 -0.0279781 0.500768 +0.475376 0.190794 0.483408 +-0.426764 -0.488009 0.445376 +0.247506 -0.503613 0.0636111 +-0.14986 -0.466327 0.492484 +0.476846 0.0934702 0.462477 +0.474349 -0.462482 -0.448822 +-0.415836 -0.496004 -0.336225 +-0.482897 -0.451075 -0.112867 +0.448224 -0.11091 -0.486208 +0.371254 -0.487209 0.459688 +0.0125424 -0.340658 -0.497944 +0.499995 -0.274441 -0.0350759 +0.490159 -0.0484525 0.00259824 +0.487505 0.443206 0.448531 +0.249866 0.507342 -0.0378986 +0.229801 0.505588 0.00082569 +0.279606 -0.511547 0.283151 +0.50245 0.0892542 0.428709 +-0.504907 -0.123304 -0.20363 +-0.489616 -0.0588109 0.434943 +0.07903 -0.108136 0.5008 +0.375993 0.502959 0.15865 +-0.271233 0.505811 -0.0327945 +-0.184372 0.493305 0.231475 +0.326635 -0.492133 0.448128 +-0.318664 -0.499117 0.389436 +0.334014 0.479841 -0.461352 +0.127467 0.0538733 0.497379 +0.459741 -0.413979 0.477997 +-0.0443313 0.360168 -0.512466 +-0.506808 -0.240348 0.424966 +-0.288113 -0.250341 0.497646 +0.499665 -0.277668 -0.415715 +0.501399 0.280457 0.173239 +0.23307 -0.491097 0.181295 +0.141562 -0.385223 0.506158 +0.511613 0.389492 0.173739 +0.406581 0.384464 0.494772 +0.428032 -0.429434 -0.499202 +0.499296 0.37074 0.132587 +0.13605 -0.497579 -0.166006 +0.209627 0.479738 -0.47977 +-0.50561 0.258145 0.237807 +0.436606 -0.443534 -0.485658 +-0.467009 0.477145 -0.405517 +-0.49984 -0.392991 -0.423767 +0.451373 -0.48456 -0.0166895 +0.493792 -0.271274 0.436579 +-0.153783 -0.497473 0.355417 +0.512171 -0.206729 0.262213 +-0.462675 0.445167 -0.472182 +0.503343 0.427845 -0.0942685 +-0.505373 -0.290047 0.377786 +-0.499709 0.439026 0.443139 +-0.289961 -0.511754 -0.24673 +0.19499 -0.0661223 0.503837 +-0.371808 -0.0269936 -0.496295 +-0.373556 0.0297859 -0.497443 +-0.330206 -0.500418 -0.276 +0.499515 0.160109 0.348946 +-0.164036 0.45742 0.478193 +-0.328819 -0.51478 -0.216274 +0.449322 0.48786 0.242817 +0.126206 -0.478063 -0.460579 +0.0402985 -0.482455 0.464444 +-0.0994894 -0.495299 -0.426347 +0.16879 -0.375907 0.512023 +0.502331 -0.334094 0.263009 +0.437366 0.421354 -0.490602 +0.511124 -0.359641 0.344781 +0.453467 0.312935 -0.492566 +0.329122 -0.516482 0.370059 +-0.387079 0.494366 0.44698 +0.466625 0.218861 -0.470662 +0.457798 -0.150441 0.482496 +-0.418443 0.465776 -0.488895 +0.4088 0.501209 0.217255 +-0.406934 0.503066 0.0660711 +0.312687 -0.498098 -0.25794 +0.180635 0.201416 -0.499909 +0.349132 -0.161571 -0.503538 +-0.389158 0.503246 0.00962747 +-0.433367 -0.413375 0.489171 +0.466585 -0.317022 0.493768 +-0.501434 0.166812 -0.311286 +0.257811 -0.49356 0.234683 +0.0875454 0.486899 0.453705 +-0.318561 0.494958 0.446049 +0.277586 -0.00834951 0.494695 +-0.262219 0.504611 0.200166 +-0.229219 0.506095 0.417918 +0.452778 0.111101 -0.481479 +0.133336 0.491645 0.447276 +0.200901 0.490014 0.0414842 +-0.49442 -0.421317 0.426648 +-0.428163 0.509212 -0.228508 +-0.315946 0.49974 -0.42263 +0.279236 0.497158 0.417307 +-0.489699 -0.352512 0.444816 +0.0863312 0.505117 0.0908735 +0.256178 0.348739 -0.51468 +0.512711 -0.32294 0.386543 +0.508863 -0.378918 0.397013 +-0.155505 0.501947 0.349645 +0.500289 -0.440647 0.340946 +-0.030816 0.504589 0.437533 +-0.125445 -0.0938168 -0.4937 +0.477981 0.0405356 0.458858 +-0.37392 0.505374 -0.254017 +0.501121 -0.205713 -0.317905 +0.502403 -0.172353 -0.0626427 +-0.512925 0.411667 0.323663 +0.177542 0.471268 0.480587 +-0.353715 0.390891 -0.513438 +0.152064 -0.103549 0.50277 +-0.292705 0.499021 0.313985 +-0.389694 -0.497174 0.457972 +-0.44006 0.218582 -0.492951 +0.368204 0.508898 0.284307 +-0.139399 0.509166 -0.00245276 +-0.0138883 0.470537 0.488408 +0.349547 0.499129 -0.15301 +-0.493069 0.109748 0.248653 +-0.501697 0.166873 0.293732 +0.336785 0.499179 -0.0345595 +0.484179 0.00385718 -0.4612 +0.329002 0.501858 0.0156999 +-0.296257 0.510397 0.381294 +0.18735 -0.511668 0.377727 +0.17626 -0.492701 0.45136 +-0.47663 0.302875 0.470377 +-0.0580429 0.453066 0.49496 +-0.474833 0.461372 -0.0489507 +0.381981 0.461687 -0.471991 +0.323054 0.349479 -0.519228 +-0.351545 -0.46515 -0.497006 +0.285392 -0.129917 0.510507 +0.327353 0.495968 0.425262 +0.496624 -0.336898 -0.145353 +-0.413634 -0.470671 0.47208 +0.479881 0.469998 0.381979 +0.342994 0.514178 0.361914 +0.349964 0.498119 0.109197 +0.365744 0.499105 0.0518944 +-0.509872 -0.297972 -0.365019 +0.506649 0.0396703 0.191597 +0.114756 0.479044 0.458191 +0.217641 -0.200277 -0.498436 +0.0142327 0.492324 0.248069 +0.493622 -0.454732 -0.234107 +-0.161276 0.497154 0.176207 +0.489666 -0.22203 0.469679 +0.223193 -0.0680984 0.490375 +0.235069 -0.147848 0.500427 +0.496409 0.115744 0.22405 +0.496027 0.167489 0.243855 +0.116248 0.48987 0.0898033 +0.475148 -0.47693 0.235969 +0.0988071 0.506097 0.0643583 +-0.442015 0.498611 0.276565 +0.302631 0.498775 -0.134079 +0.303966 0.497568 -0.0864494 +0.49917 -0.0301441 -0.158132 +-0.257123 0.221807 -0.503285 +-0.159571 0.27639 0.496265 +0.50425 0.390199 0.0251044 +-0.416469 -0.495286 -0.431395 +-0.465036 -0.470614 -0.428215 +-0.342827 -0.508658 -0.0127583 +-0.226712 0.487015 0.463554 +0.0280426 0.498409 0.170626 +-0.167964 -0.498158 0.330211 +-0.498192 -0.263957 0.00422267 +-0.0156926 0.507778 0.367297 +0.0258555 0.502014 0.375634 +0.510598 0.214653 0.275247 +0.340761 -0.455739 0.492017 +-0.282851 -0.04251 -0.505744 +0.0375036 0.498917 -0.2979 +0.450071 -0.491309 -0.0964163 +0.306685 0.486517 0.456738 +-0.0528786 0.508773 0.391074 +-0.461155 0.480576 0.417786 +-0.131593 0.497062 0.437423 +-0.439226 0.239052 0.489966 +-0.144043 0.502936 0.135794 +0.206915 0.503702 -0.0750526 +0.466754 0.449052 0.467707 +-0.216388 0.503625 0.335863 +-0.434604 0.48348 0.463305 +-0.496102 0.300648 -0.237855 +0.43436 0.498488 0.413702 +0.0163666 0.42296 0.50577 +-0.485483 -0.00896095 -0.461285 +0.492809 -0.0483412 -0.144514 +-0.472616 0.487112 0.121586 +-0.504883 0.0845841 0.436988 +-0.466668 -0.0467544 -0.482707 +-0.0701595 0.496768 -0.360626 +-0.430068 -0.500934 -0.185372 +0.494338 -0.0400872 -0.0495281 +0.503476 -0.250831 -0.245346 +-0.490316 0.464885 0.0601366 +-0.431435 0.261946 -0.50216 +0.295586 0.495679 0.159613 +-0.0753908 0.498833 0.326771 +0.322243 0.501194 0.117141 +0.458943 0.224481 -0.488979 +-0.00807915 -0.484607 -0.471018 +0.0874157 0.498996 0.427907 +-0.110514 0.49345 0.275402 +0.260732 -0.425399 -0.49707 +-0.341523 0.467066 0.480556 +-0.289829 -0.476886 0.472886 +-0.283664 0.208871 -0.508583 +-0.409829 0.503039 0.113332 +-0.254246 0.0410035 -0.494696 +-0.395508 -0.141366 -0.501427 +-0.430613 0.501075 0.311666 +-0.376542 0.507785 0.31852 +-0.492326 0.187456 0.468823 +0.506122 -0.204482 0.188678 +0.338017 -0.070821 0.498493 +-0.485384 0.468144 -0.364803 +0.167087 -0.496641 0.222927 +0.109984 -0.496827 0.195759 +0.503352 -0.000378356 -0.415524 +0.243644 -0.497185 -0.178953 +0.0976387 -0.132544 -0.489801 +-0.494186 0.451637 0.206879 +-0.492246 -0.163707 -0.465859 +-0.269306 -0.158889 0.497714 +0.0446565 -0.498224 0.32307 +-0.111173 -0.44579 0.500708 +0.417766 0.505247 -0.237382 +0.301101 -0.446225 -0.489368 +-0.270458 -0.498188 -0.31293 +-0.372844 0.364799 -0.499586 +-0.423745 0.506613 0.158165 +-0.0460218 0.507661 0.00361463 +0.50813 -0.291661 -0.105333 +0.0464028 0.507593 -0.15413 +-0.00311363 -0.391667 -0.497419 +0.0385136 -0.0303836 -0.491092 +0.208754 -0.500486 -0.406502 +0.289962 0.0185575 0.511165 +-0.505396 0.118788 0.378633 +-0.203558 -0.505105 0.299064 +-0.151965 -0.500591 0.306102 +-0.2517 0.253854 -0.500308 +-0.282286 -0.499996 0.342295 +0.460756 -0.0800112 -0.477573 +-0.126471 0.467974 -0.472183 +0.503223 0.30241 0.276618 +0.287358 -0.43113 -0.51004 +-0.501108 -0.268557 -0.0693151 +0.461114 0.489305 0.379301 +0.348292 -0.403727 -0.50717 +-0.0673818 -0.0294295 -0.504982 +-0.435579 -0.463827 0.481975 +0.495193 0.210156 -0.042535 +-0.252586 0.241335 0.507954 +-0.273623 -0.511189 0.0733366 +0.482956 -0.462637 -0.326201 +-0.505563 0.397734 0.125742 +-0.318409 -0.130638 0.508646 +-0.121945 -0.503067 -0.19192 +0.0931222 -0.282833 0.505165 +0.0435874 -0.0883884 -0.505732 +-0.23351 -0.507507 0.365359 +-0.502309 -0.266284 -0.0958948 +-0.0961313 -0.0127264 -0.500526 +-0.483845 -0.458094 0.429181 +-0.21462 -0.503542 0.152309 +0.243356 -0.495568 -0.445206 +0.0716057 -0.0660665 0.506455 +-0.0735383 0.160561 -0.501416 +-0.10095 0.170551 -0.492745 +-0.121432 -0.187683 -0.497208 +0.384179 -0.515462 -0.243549 +-0.0922762 -0.19825 -0.499258 +-0.505165 -0.103314 0.361009 +-0.440518 -0.13966 -0.48823 +0.507364 -0.352417 -0.121307 +0.486708 0.471232 0.0745881 +-0.482943 -0.302798 0.456854 +0.469914 0.465693 -0.371836 +-0.331179 -0.306275 -0.508503 +0.320231 0.0190402 0.510344 +-0.118713 -0.112974 0.504874 +0.406771 0.169869 0.497032 +-0.493221 0.256702 -0.206909 +-0.412968 -0.404353 0.503227 +-0.129531 0.0402712 -0.492337 +-0.0739979 0.273701 -0.501632 +-0.23092 -0.479624 -0.458175 +-0.222768 -0.506788 -0.152205 +0.491851 -0.327085 -0.439123 +0.50662 -0.241985 -0.215429 +0.476966 -0.472349 -0.141198 +0.475897 0.468758 0.459178 +-0.125271 -0.157366 -0.493953 +0.466195 -0.384627 -0.475812 +0.273407 -0.500319 0.307752 +-0.517793 0.334435 -0.320961 +0.469928 -0.484281 -0.113561 +-0.368486 0.483711 0.483806 +0.195329 -0.500182 -0.017652 +0.416414 -0.510908 -0.192701 +-0.0538128 -0.339086 0.502194 +-0.340501 -0.421692 -0.503757 +-0.324736 0.49485 -0.443475 +0.35809 0.208888 -0.513769 +0.143856 -0.480044 0.474289 +-0.398749 -0.324627 0.498431 +-0.129726 0.150228 0.502914 +-0.462683 0.492485 0.250235 +-0.271481 0.44302 0.486941 +-0.246975 0.431038 0.493421 +-0.0270675 0.394852 0.510492 +-0.0994795 -0.110173 -0.50615 +-0.500411 0.20773 -0.270084 +0.468346 -0.41593 -0.487478 +0.327126 -0.501998 0.0671992 +0.321472 -0.504931 0.0162387 +-0.470378 -0.4712 -0.143889 +-0.499093 0.426513 0.0457903 +-0.496772 0.143748 -0.00751674 +-0.479437 0.463973 -0.419202 +-0.389604 0.150327 -0.499642 +-0.0818206 0.473228 -0.491038 +-0.337989 0.36713 -0.501752 +0.294051 -0.49366 0.448756 +-0.346441 -0.482971 -0.455241 +-0.40471 0.34753 -0.501801 +0.238113 -0.49902 -0.420249 +0.00912699 -0.173731 -0.508617 +-0.246594 0.159236 -0.496726 +-0.290394 -0.513639 0.25632 +0.357355 -0.517529 -0.331132 +0.508875 -0.0554792 -0.341285 +0.113572 -0.500043 -0.281974 +0.0378708 -0.468551 0.476678 +0.26085 -0.504746 -0.249773 +-0.491555 0.00993286 -0.0803339 +0.116763 0.497197 -0.233363 +-0.45721 0.338889 0.48226 +-0.137459 -0.496283 -0.35066 +-0.397334 -0.501345 -0.186512 +0.503663 0.317957 -0.05426 +0.222593 -0.00598502 -0.506729 +0.434244 -0.494312 -0.314586 +-0.284564 -0.165501 -0.509611 +0.507601 -0.231515 -0.297836 +0.502879 -0.0103334 -0.230241 +0.506072 -0.291598 -0.322589 +-0.511748 0.278592 0.165372 +-0.227484 -0.402396 0.496878 +0.0503354 -0.50811 -0.292424 +0.313064 -0.466131 -0.480697 +-0.495964 0.12876 0.184807 +0.0313375 -0.184277 -0.504554 +0.0787984 -0.150546 -0.500516 +-0.187577 -0.505446 0.13311 +-0.159954 -0.507196 0.116077 +-0.507925 -0.204709 -0.198224 +-0.494524 -0.0590528 0.218836 +-0.505843 0.414951 -0.0599898 +-0.0657645 -0.357102 -0.498485 +-0.491576 0.191992 -0.182176 +-0.407031 -0.49853 0.446225 +-0.51482 0.251003 0.350367 +0.394594 0.501924 -0.42083 +-0.232428 -0.424077 0.491706 +0.507419 -0.353643 0.375302 +-0.500299 -0.423647 -0.218656 +-0.502911 -0.389448 -0.259998 +-0.409912 -0.505385 0.0980659 +0.355972 -0.507677 0.195581 +-0.246031 -0.385886 0.512505 +-0.282421 -0.122249 0.495832 +-0.468176 -0.223948 0.476459 +0.454463 -0.139706 -0.475615 +-0.464576 -0.494972 0.378412 +0.357275 -0.496878 0.229836 +-0.112494 0.31938 0.506468 +-0.491556 0.439374 0.0674945 +0.0149256 -0.162358 0.508752 +-0.301279 -0.511818 0.291309 +-0.139654 -0.495982 0.329685 +0.0284802 0.496287 -0.0987178 +-0.183048 -0.496971 0.356313 +-0.507894 0.246818 0.163268 +-0.508808 0.237049 0.134609 +0.00480958 -0.510601 -0.287083 +0.501636 0.437881 -0.359809 +-0.428806 0.0751311 -0.503331 +-0.158724 -0.49062 0.0834249 +-0.296232 -0.506689 -0.406283 +0.380676 -0.264095 -0.516287 +0.487265 -0.442416 -0.27802 +0.299828 0.0983032 0.499269 +0.33351 0.100212 0.509952 +0.31964 0.0716809 0.50715 +-0.14762 0.221271 -0.497336 +-0.139712 0.250904 -0.495051 +0.0780569 -0.49426 -0.0849627 +0.509771 -0.308546 0.193253 +0.244887 0.124851 0.50818 +0.379983 0.273343 -0.51403 +-0.502209 0.420777 -0.262337 +-0.0696993 -0.509949 -0.221298 +0.0339589 -0.49465 -0.110445 +0.490698 -0.193364 0.454793 +-0.164826 0.508278 -0.129115 +-0.486173 0.448254 -0.21753 +0.212326 -0.493013 -0.139235 +-0.502674 0.299521 0.404829 +0.465305 0.388501 -0.478279 +0.513872 -0.323689 0.216629 +0.462751 0.00256896 0.481167 +0.505348 0.036333 0.389145 +0.0391554 -0.387194 -0.513456 +-0.360392 -0.385294 -0.50288 +-0.310157 -0.356725 -0.508064 +0.472157 0.485878 0.0796619 +0.378175 -0.512077 0.419016 +-0.401141 0.0923739 0.498275 +-0.389704 0.119819 0.512948 +0.0157193 -0.477708 0.471899 +0.432983 -0.469307 -0.461726 +-0.124936 0.00265224 -0.49126 +-0.504919 0.0712765 -0.182028 +0.147864 -0.327066 0.512544 +-0.433733 -0.505285 -0.316708 +0.496548 -0.377978 -0.171977 +0.105312 -0.493348 0.259206 +0.515496 -0.214168 0.319655 +-0.494041 -0.462352 0.261614 +0.475525 -0.486812 0.400432 +0.04748 -0.509629 0.289089 +0.46831 0.478576 -0.0226913 +0.332998 0.10355 -0.51364 +0.458583 0.239292 0.477026 +-0.481614 -0.113655 -0.476534 +0.510651 -0.134836 0.414881 +0.385437 0.305957 -0.504676 +-0.396723 -0.495526 0.156042 +0.425773 -0.047321 0.493703 +0.483177 -0.0422246 -0.465979 +0.460112 -0.470452 -0.16898 +-0.504885 -0.166024 0.399468 +-0.445812 0.480027 -0.41544 +0.403244 -0.215729 -0.513127 +0.374533 -0.503703 0.443116 +-0.504256 -0.193561 0.404369 +0.431836 0.489039 0.460074 +0.195346 0.348701 -0.508302 +0.41045 0.428014 -0.500593 +-0.507858 -0.244738 0.262118 +-0.149476 -0.0161285 -0.49188 +0.439441 -0.0814351 -0.501078 +0.405109 0.508467 -0.0771707 +0.418166 0.508402 -0.0514563 +0.0383594 0.12662 -0.505325 +0.509079 0.371378 -0.299196 +0.232586 -0.504072 0.448892 +-0.507086 0.0515281 0.0823813 +0.502184 0.265271 -0.16067 +-0.511985 -0.346858 0.00539576 +-0.511625 0.323559 0.41963 +-0.133954 0.202179 0.495818 +0.226566 0.349439 -0.501127 +-0.412723 -0.0934708 0.507315 +-0.0867294 -0.49675 -0.153738 +-0.00133491 0.43802 -0.489236 +-0.465261 0.482267 -0.0712748 +-0.0994519 0.261024 0.505743 +0.499556 -0.290122 0.171537 +0.510491 -0.264158 0.148257 +0.485282 -0.454112 0.381948 +-0.4978 0.256395 0.116521 +-0.503771 0.296463 0.140806 +0.418166 -0.49348 0.433422 +-0.50313 0.37442 -0.276855 +0.451156 -0.486004 -0.239047 +-0.512262 -0.276796 -0.209301 +0.426318 -0.479588 0.450148 +-0.218993 -0.378104 -0.512737 +0.00841831 0.0977768 0.503385 +-0.273487 0.115121 -0.507319 +0.00660631 0.0638448 0.490346 +-0.07025 -0.492969 0.449481 +-0.304195 0.508469 -0.398327 +-0.00512728 -0.507861 0.0901858 +-0.495837 -0.426562 -0.188899 +-0.473536 -0.248082 -0.466436 +0.220265 -0.461944 -0.494156 +-0.496029 -0.225071 -0.424729 +0.50195 -0.157941 -0.0408449 +-0.0191466 -0.500583 0.442446 +0.18638 -0.449382 0.481259 +0.403526 -0.512259 -0.0154673 +0.0109646 0.196535 0.51012 +-0.511529 -0.0343679 -0.320521 +-0.147504 -0.208412 -0.496002 +0.44555 0.483929 0.4267 +-0.414444 0.0662453 0.50347 +0.489543 0.134097 0.0928638 +0.0889821 -0.496887 -0.43105 +0.502845 0.298738 -0.176824 +-0.200901 0.422923 -0.496413 +-0.508365 -0.275872 -0.042305 +0.110207 0.508184 -0.173493 +-0.50753 -0.316399 -0.00618334 +0.197479 -0.476895 0.458295 +0.136712 -0.457537 0.479784 +-0.481781 -0.466577 -0.0709846 +-0.191191 0.49235 0.0324655 +-0.243434 -0.493358 0.0631129 +-0.344379 -0.50546 -0.368814 +0.501582 0.295074 0.449036 +0.303864 0.438689 0.490765 +0.136863 0.508112 -0.252052 +0.0671448 0.164472 0.499099 +0.495738 -0.294872 0.216891 +-0.415735 0.493956 0.342682 +0.117715 0.136921 0.500886 +-0.0990809 -0.169065 -0.508099 +-0.0769062 -0.154212 -0.497859 +-0.10035 -0.14048 -0.49337 +-0.50363 0.0400211 0.0509514 +0.489908 -0.0261775 -0.452212 +-0.0637019 -0.309063 -0.496533 +0.111407 0.227449 -0.503805 +0.384801 0.161577 0.502136 +-0.506269 -0.298315 -0.28495 +0.110843 -0.506619 0.167396 +0.500027 0.321513 -0.455351 +-0.167916 0.149449 -0.498487 +0.383411 0.489615 -0.450939 +0.252331 0.498006 0.0437778 +-0.250831 0.374848 0.511398 +0.0342557 -0.107221 0.492195 +-0.440482 -0.489022 -0.418926 +-0.0774738 0.134568 0.497518 +-0.489518 -0.435909 -0.274723 +-0.239101 -0.499568 -0.431559 +-0.514062 0.025511 -0.39253 +-0.149019 0.47347 0.472672 +0.181599 -0.502156 -0.0467224 +-0.0381666 -0.469232 -0.471838 +-0.22849 0.103713 0.493965 +-0.502377 0.11323 -0.436114 +-0.493493 0.0884235 -0.413372 +-0.267435 -0.505618 -0.420401 +-0.178924 0.207879 -0.506563 +0.490233 0.445323 -0.0754957 +-0.367747 0.470217 -0.475404 +0.427295 -0.166489 -0.502907 +0.507536 -0.400966 -0.242379 +0.504683 -0.371217 -0.228564 +-0.217428 0.297453 0.503229 +-0.191157 -0.0543094 0.494501 +-0.158025 -0.0663997 0.501714 +0.24213 0.178765 0.493918 +-0.4436 -0.0607428 -0.493526 +-0.470378 0.350364 0.466733 +0.495632 -0.013136 0.332395 +0.40577 -0.502046 0.412608 +-0.50434 -0.250349 -0.2371 +0.0578904 -0.365265 0.503125 +-0.264887 -0.359408 -0.513876 +-0.284795 -0.344993 -0.504244 +0.227659 0.152155 0.500456 +-0.0594442 -0.492184 -0.156235 +-0.0139698 -0.504237 0.0638397 +0.0625794 -0.508233 -0.31752 +-0.129436 -0.506656 0.307504 +-0.111834 -0.508506 0.323477 +-0.356729 0.303886 -0.518795 +-0.457648 0.298507 -0.486508 +0.509195 -0.0792718 -0.0683686 +0.104962 0.20495 0.493202 +0.471454 -0.421835 0.464574 +0.232003 0.494444 0.226477 +0.0924657 0.148165 0.505983 +0.0386431 -0.139049 0.507109 +0.455411 -0.485551 0.194046 +0.485267 0.440064 -0.432087 +0.506627 0.304942 -0.112951 +0.496021 0.301392 -0.145296 +0.503797 0.272885 -0.123691 +-0.0278331 -0.491752 0.0830628 +0.480177 -0.460936 -0.259102 +0.0871938 0.231967 0.494582 +0.0377261 0.213937 0.495502 +-0.511476 -0.208259 0.271106 +0.499797 -0.40022 -0.276269 +0.386347 -0.504255 -0.345964 +0.412558 -0.503291 -0.328767 +-0.452023 0.481716 0.468427 +0.50816 -0.227862 0.288799 +-0.499411 -0.00256934 -0.326574 +0.187569 -0.49757 -0.348296 +-0.133673 -0.492388 0.132125 +0.141863 -0.0213173 0.497172 +0.453286 -0.226727 0.496672 +-0.465962 0.310108 0.491481 +-0.493004 0.266957 0.139315 +-0.122477 -0.436549 -0.497678 +-0.164401 0.497861 -0.450903 +0.0606492 -0.198426 0.496292 +0.0474846 -0.169129 0.499993 +0.473697 -0.487477 -0.248563 +-0.496942 -0.0204542 -0.0910334 +0.501421 -0.108566 -0.068403 +0.0238589 -0.506303 0.0985391 +0.441906 0.488368 0.150402 +-0.509463 0.041509 -0.0702484 +0.156003 -0.507382 -0.42789 +-0.507509 0.0541653 0.199943 +-0.492626 -0.116262 0.417819 +-0.505205 -0.0646681 0.391691 +0.0989121 -0.508662 0.12736 +0.0868011 0.385791 -0.503139 +0.487446 -0.0920974 0.466034 +0.455736 0.138484 -0.48285 +-0.160583 -0.496565 0.147489 +-0.370772 -0.490534 -0.471028 +-0.160191 -0.499175 0.17664 +-0.309023 0.226143 -0.511368 +-0.359696 0.195502 -0.511587 +0.423374 0.493931 -0.290267 +-0.0925817 0.0857081 -0.489881 +0.265489 -0.508687 -0.12792 +-0.507245 0.342677 0.32822 +0.456773 -0.483507 -0.142585 +0.472633 0.387924 0.482059 +-0.0994681 -0.493366 0.0513585 +0.479687 -0.0950573 -0.464179 +0.182472 0.232504 0.495037 +0.166291 0.206415 0.490193 +-0.150117 -0.510338 -0.370642 +-0.0112015 -0.504175 -0.168845 +0.49535 -0.400225 -0.397353 +-0.387113 0.177505 0.496481 +-0.478905 0.350075 -0.468121 +-0.470956 -0.0413451 0.485238 +0.492114 -0.443935 -0.340635 +0.435453 -0.474923 0.464375 +0.241861 0.119451 -0.505997 +0.179476 -0.282244 0.497118 +0.502598 0.327198 0.41511 +-0.1318 -0.494535 0.10024 +-0.105718 -0.493009 0.117428 +-0.102932 -0.506735 0.0852511 +-0.509162 -0.00932841 -0.0270201 +-0.498273 0.0165109 -0.0485099 +0.210441 -0.501403 0.367386 +-0.516602 0.320492 -0.37099 +-0.508127 -0.0961799 0.0563879 +-0.193895 -0.378637 0.496171 +0.507245 0.391679 -0.1659 +0.347826 0.226858 0.4985 +-0.494275 -0.286994 -0.084399 +0.266365 -0.507283 -0.383326 +-0.479632 -0.0370548 -0.46414 +-0.0347223 -0.498513 -0.142266 +-0.438839 0.0199555 -0.488587 +0.0323827 -0.502538 -0.0346123 +0.0142468 -0.507602 -0.0109959 +-0.497639 -0.128978 -0.015246 +-0.158729 0.186605 0.502078 +0.440374 0.352227 -0.501707 +-0.189867 0.184841 0.492118 +0.433277 -0.499942 0.0393781 +0.338962 0.14497 -0.509233 +-0.0338633 -0.503778 0.32198 +-0.0491812 -0.504961 0.350716 +0.221243 -0.468911 0.467893 +0.408658 0.508573 -0.266517 +0.419259 0.495295 0.143055 +0.208984 -0.495387 0.0122438 +-0.498441 0.351865 -0.0344871 +0.339612 -0.50537 0.093317 +0.402925 -0.202762 0.501508 +-0.480813 -0.439075 0.43682 +0.493464 -0.442388 0.199394 +-0.29036 -0.511158 -0.192755 +0.457329 0.483048 0.0515667 +0.326774 -0.188843 0.502213 +0.47944 0.477555 0.135435 +0.357216 -0.501363 0.0693742 +-0.501335 0.363464 0.358263 +-0.510057 -0.256543 0.0306754 +0.284261 -0.356441 0.505822 +-0.498943 -0.431372 -0.0696698 +-0.490877 -0.109154 0.441762 +0.00821664 0.465031 0.490984 +-0.508705 0.381858 -0.0463709 +0.127386 0.0781336 0.508392 +0.182216 0.0672102 0.503703 +-0.280244 -0.478557 -0.458645 +0.0310964 0.470961 0.478147 +0.241276 0.226375 0.498102 +0.055454 -0.137616 -0.49531 +0.214301 -0.436114 -0.492037 +-0.0305116 -0.4918 -0.252057 +-0.306348 -0.474181 -0.48135 +0.509868 0.115445 0.35469 +0.172582 -0.493365 -0.271111 +0.162239 -0.503255 -0.29897 +-0.269242 0.512602 -0.00022896 +0.133169 -0.500235 -0.305175 +-0.0379039 -0.0449318 0.503096 +0.106738 -0.339668 -0.505161 +-0.245043 -0.506564 -0.130915 +-0.293266 -0.507441 -0.0957901 +-0.491382 0.185639 -0.242514 +-0.507091 -0.220045 0.403373 +-0.0764033 -0.490136 -0.0386405 +-0.0927746 0.113378 -0.497673 +-0.0963822 0.141458 -0.498665 +-0.14298 0.33034 0.50111 +-0.194448 0.317481 0.503742 +-0.444709 0.491146 -0.307403 +0.503995 0.104695 0.0699366 +0.344284 0.196161 0.496824 +0.229949 -0.504419 -0.0149797 +-0.51153 0.331269 0.364209 +0.10806 0.483916 -0.476752 +-0.512031 0.300808 0.376686 +-0.426961 0.0913578 0.496185 +0.239345 -0.510082 0.0170048 +0.267505 -0.496701 0.0239551 +-0.50868 0.263416 0.305675 +-0.498515 0.222152 0.259811 +0.387762 0.468585 0.477677 +-0.0478353 -0.174012 0.501629 +0.511271 -0.410756 -0.131677 +0.493524 -0.0670087 0.144491 +-0.130383 -0.202285 0.503257 +0.0745782 0.0783066 -0.499231 +-0.16293 -0.193314 0.494333 +-0.479514 0.466223 -0.462404 +0.176762 -0.494403 0.252283 +0.221763 -0.508667 0.283738 +0.447819 -0.0627505 0.499461 +-0.497126 0.451185 0.123262 +-0.501567 0.225867 0.441761 +0.405407 -0.0597093 0.501937 +-0.302367 0.511974 -0.0494672 +0.407835 0.285176 -0.498096 +-0.493587 -0.463121 -0.13529 +-0.0388252 0.493661 -0.425414 +-0.503472 -0.421712 -0.142138 +0.485496 -0.452107 0.02697 +-0.513798 0.00621524 0.31266 +-0.506785 -0.00425552 0.282598 +-0.51286 0.0273614 0.287921 +-0.0243284 -0.500375 -0.19882 +-0.0412784 -0.49987 -0.224421 +0.289953 -0.505233 -0.104018 +0.509922 0.323339 0.156535 +-0.502563 0.198177 -0.301558 +-0.0683012 0.0703843 -0.506858 +0.199759 -0.496832 -0.0753315 +-0.508566 0.191157 -0.332484 +0.271892 0.181518 0.498989 +0.25998 0.153625 0.510592 +0.191576 -0.503043 0.0361501 +-0.504595 0.397002 0.00388823 +0.351437 0.502093 0.433018 +-0.0823108 -0.492553 0.196292 +0.508359 0.251267 0.409952 +0.509403 0.254839 0.364761 +0.492318 0.370907 0.444382 +-0.438885 0.495203 0.173041 +-0.214525 -0.30604 0.503016 +-0.199406 -0.494914 0.247687 +0.234878 -0.49945 0.406737 +0.199677 -0.5093 -0.2722 +0.442955 0.484325 0.305966 +0.502776 -0.320129 -0.168056 +0.509454 -0.312563 -0.145216 +0.375339 -0.225249 0.500974 +0.406506 -0.234116 0.49385 +-0.11642 -0.217282 -0.490846 +0.494944 -0.0506823 -0.0701234 +0.511504 -0.261801 -0.309321 +-0.483115 0.366115 -0.449224 +0.505491 0.00110585 -0.083884 +0.235408 0.494744 -0.165527 +-0.00890906 0.353049 0.508923 +0.0121087 0.329715 0.506626 +0.502669 0.028079 -0.0711673 +-0.0562069 -0.499747 0.181775 +0.515054 -0.361471 0.247682 +-0.127989 0.261934 0.497815 +-0.510451 0.305335 -0.129012 +-0.507509 -0.00297528 0.0073393 +-0.135758 0.296831 0.512604 +0.495272 -0.428715 0.25717 +-0.178891 0.447552 0.494284 +-0.388162 -0.393339 0.499754 +-0.269924 0.124643 0.494747 +-0.430739 -0.489513 -0.218776 +-0.450711 -0.488133 -0.197948 +0.490027 -0.430335 0.456248 +0.402164 0.503055 0.163087 +-0.405893 0.401999 0.502804 +0.439759 -0.502866 -0.142757 +0.482584 -0.461287 -0.35752 +0.413184 0.124657 0.503669 +-0.496132 0.023341 -0.0156671 +-0.491985 0.0310692 0.0175993 +-0.506334 0.0108567 -0.437021 +-0.172932 0.174187 -0.496479 +0.428004 -0.486516 -0.431366 +0.0346788 -0.303402 0.49791 +0.477091 0.45579 -0.430596 +-0.0774342 0.00235756 0.493154 +-0.0945874 -0.512819 -0.400884 +0.0519547 -0.496403 0.223236 +-0.443968 0.502073 -0.153962 +0.492499 0.449479 -0.410876 +0.0396538 -0.514313 0.35502 +-0.459231 -0.480164 -0.00832268 +-0.0160677 -0.504867 0.346734 +0.177226 -0.494136 -0.101298 +0.185433 -0.499434 0.354797 +0.209139 -0.503037 0.338179 +0.497738 -0.0242981 -0.408905 +-0.265187 -0.503039 -0.0770189 +-0.183269 -0.312399 0.511434 +0.45332 -0.485909 0.0370496 +-0.20806 0.444458 -0.500187 +0.0941982 -0.389199 0.51371 +0.246996 -0.486788 -0.468272 +-0.497025 0.424353 0.208916 +0.497963 0.128151 -0.142301 +-0.257463 0.209146 0.499537 +-0.264007 0.173133 0.497111 +-0.483762 -0.469241 0.0332359 +-0.299089 0.171484 0.493713 +-0.50394 0.174643 -0.277667 +0.344161 -0.49333 0.470361 +0.508515 -0.143396 -0.0721632 +-0.499156 -0.375501 0.456989 +-0.00347206 -0.0568146 0.49061 +0.0349757 -0.0694107 0.492935 +-0.150748 0.364445 -0.495644 +0.493774 0.171377 -0.10664 +0.492346 0.193404 -0.114816 +-0.453191 -0.484961 -0.227087 +0.490801 0.0446169 0.060085 +-0.197281 0.433893 0.502676 +-0.487699 -0.438793 -0.425136 +0.496882 0.145692 -0.0965865 +0.492372 0.123241 -0.113459 +0.505199 -0.158776 -0.362799 +-0.500398 -0.0418406 -0.171227 +0.444284 -0.374758 0.496567 +-0.439184 0.501113 -0.372056 +-0.494913 -0.0650266 0.411311 +0.0132021 -0.497021 -0.198602 +0.0488838 -0.491038 -0.181337 +-0.152603 0.0630994 0.505886 +-0.117847 0.12268 -0.495017 +-0.14811 0.130539 -0.505749 +-0.50102 -0.323157 0.269645 +-0.500201 0.431922 -0.422682 +0.0173067 0.329101 -0.498454 +0.461319 0.483973 -0.11377 +-0.472302 0.0437244 -0.476638 +-0.469078 -0.472563 -0.274581 +-0.482346 -0.449852 0.113954 +0.0471598 -0.498545 -0.216154 +-0.00129075 -0.495311 -0.258697 +-0.510177 0.032009 -0.421239 +-0.0703323 -0.31217 0.503076 +-0.184847 -0.494221 -0.433141 +0.332006 -0.371283 0.518742 +0.305317 -0.371114 0.512278 +-0.504361 0.0448745 0.347536 +-0.468489 0.474537 0.049913 +0.316304 0.340401 0.514605 +-0.182667 -0.365722 -0.497579 +0.263485 -0.453893 0.491392 +-0.458795 0.460735 -0.459767 +0.466888 0.298449 -0.480292 +-0.489931 -0.0847554 0.135684 +-0.503381 -0.0111674 -0.214104 +-0.490006 0.0824264 -0.466329 +0.137708 -0.504603 0.210864 +-0.29409 0.0118374 -0.508811 +0.474685 0.464517 0.186844 +-0.488477 0.272162 0.469365 +0.312437 0.511641 -0.347191 +0.430649 -0.497885 -0.0128112 +-0.423208 -0.504342 0.292984 +-0.507963 -0.261402 0.163084 +-0.490228 0.426683 -0.116892 +-0.438578 0.50162 0.242777 +0.458898 -0.364337 0.48559 +-0.491352 0.0846695 0.459648 +0.481063 -0.0323725 0.450453 +-0.495729 0.0560937 -0.00544293 +-0.41806 -0.150007 0.492583 +0.379649 0.491217 0.437206 +-0.318202 0.47307 0.474344 +-0.501204 0.112857 -0.0177465 +-0.296842 0.497581 -0.442769 +-0.209439 -0.135192 -0.494927 +0.226838 -0.497006 0.232089 +0.496026 -0.074647 0.332354 +0.0782504 0.449006 0.492262 +0.0291129 0.0485143 0.509632 +0.490803 0.443967 0.338322 +0.0441813 0.197994 -0.491985 +0.101989 -0.0851123 -0.491407 +-0.492093 0.300196 0.453713 +-0.48818 0.162996 -0.442048 +-0.490803 0.231089 -0.468961 +-0.131105 0.333751 -0.50162 +-0.157001 -0.507025 0.0505732 +-0.128251 -0.500035 0.0340612 +0.371805 0.451984 -0.49038 +0.292731 -0.209958 -0.507012 +0.14645 -0.446834 -0.482508 +-0.171219 -0.158701 0.509534 +0.486927 -0.450766 -0.106023 +0.507099 0.44389 0.363241 +0.192609 -0.193903 -0.493187 +0.456461 -0.438585 -0.47388 +0.459331 -0.0529797 0.480216 +-0.513472 -0.0752765 0.335693 +0.47343 0.462802 -0.448378 +-0.0110324 -0.257648 -0.501452 +0.475863 -0.430129 -0.45563 +-0.102597 0.484326 0.466624 +-0.160938 -0.397896 -0.507875 +-0.194121 -0.402586 -0.504358 +-0.152884 0.464474 -0.474243 +0.206396 -0.4898 -0.108879 +-0.412174 0.129791 -0.510229 +0.462122 -0.357199 -0.479774 +-0.503839 0.277781 -0.110223 +-0.11508 -0.510602 -0.294337 +0.47448 0.0313656 -0.46719 +-0.445683 0.496713 0.150367 +0.122557 -0.189516 0.508737 +-0.515745 0.287334 0.314699 +0.0769251 -0.17285 0.505912 +-0.480043 -0.471369 0.00275415 +0.226241 -0.494417 -0.0641645 +0.211972 -0.504005 -0.0438276 +-0.353976 -0.190225 0.500517 +-0.329139 -0.163386 0.509716 +0.49278 0.440572 0.0277743 +-0.502241 -0.110743 0.325405 +-0.507596 -0.119111 0.291605 +0.122176 0.471973 0.480013 +-0.105169 -0.48845 -0.446027 +0.482499 0.478167 0.0532297 +-0.488355 -0.471327 -0.346517 +-0.468555 0.402 0.479094 +0.417754 -0.509483 0.386758 +-0.496997 -0.414004 0.325588 +0.399081 0.487766 -0.435951 +0.243935 -0.508994 0.208796 +-0.298049 -0.500282 -0.437568 +0.169045 -0.184844 0.504285 +-0.503758 -0.307535 -0.0366763 +-0.298416 0.508441 -0.11126 +0.182643 -0.427956 0.503168 +0.496776 0.0727507 -0.176186 +0.207949 0.16729 -0.506366 +-0.479466 -0.461461 0.0633404 +0.00322549 -0.367089 -0.499936 +-0.487951 -0.443936 0.0964702 +-0.0306745 -0.332549 -0.495146 +0.49128 -0.423392 -0.429432 +0.135788 0.206774 0.490356 +-0.441483 0.442027 0.495166 +0.243967 -0.492615 0.467388 +0.314752 0.470103 0.472036 +-0.50015 -0.0257089 -0.119845 +0.495547 0.0669785 0.407918 +-0.118843 0.492147 -0.469576 +0.327416 0.517073 -0.291859 +-0.2748 0.262608 0.505907 +-0.302934 0.258234 0.5096 +-0.471251 0.0761752 -0.481272 +-0.292212 0.278896 0.51373 +0.308435 -0.354594 -0.510596 +-0.426214 -0.0886704 -0.498808 +-0.323876 -0.502943 0.205444 +-0.29384 -0.502628 0.218608 +-0.43612 0.460834 0.489125 +-0.0593427 0.439913 -0.493851 +-0.389996 -0.296129 0.502974 +-0.360542 -0.293093 0.506489 +-0.0149632 0.181155 0.492691 +0.416859 0.148837 -0.505762 +-0.21637 0.456771 0.481711 +-0.0172926 0.150549 0.507758 +-0.067243 0.161071 0.491726 +0.474873 -0.221883 -0.484308 +-0.499491 0.375339 -0.0151069 +0.496966 -0.140086 0.230824 +-0.491945 0.180561 0.0302305 +-0.478271 -0.272068 0.462991 +-0.500478 0.150781 0.0227319 +-0.408665 0.0114465 0.494754 +0.399344 -0.259022 -0.498209 +-0.449953 0.0522979 -0.489456 +0.201133 0.46425 0.477379 +0.412941 -0.241129 -0.50593 +-0.1104 0.508166 0.383344 +0.412099 -0.502181 -0.361723 +0.49182 -0.111474 -0.449934 +0.0054591 -0.447135 0.486143 +0.478805 -0.448087 0.42458 +0.118461 -0.0443019 0.493665 +0.494108 -0.413938 -0.0833304 +0.472221 0.476048 -0.187506 +0.50237 -0.436932 -0.0936661 +0.26989 -0.0991985 -0.501121 +0.181851 0.275299 -0.493039 +0.46463 -0.440646 0.47765 +0.180775 0.45652 0.49387 +0.490345 -0.440305 -0.422966 +-0.435146 -0.396087 -0.507325 +-0.509216 0.106403 -0.173014 +-0.178239 0.487559 0.441663 +0.297997 0.126995 -0.512429 +0.270852 0.123842 -0.509828 +0.289539 0.10233 -0.496461 +0.0666167 0.510583 -0.280159 +0.340975 -0.0491505 0.497562 +-0.160405 0.396793 -0.504964 +0.490433 0.006292 -0.0266519 +0.44966 0.489006 0.213437 +-0.438264 0.488283 0.049017 +-0.490447 -0.425105 0.0280085 +0.317348 -0.0534184 0.503866 +0.396393 0.0929882 -0.504406 +-0.212604 -0.50082 0.0488882 +0.488232 -0.414086 0.438012 +0.501965 -0.294722 0.399513 +-0.185851 -0.507206 0.0666361 +-0.513187 0.363957 -0.326533 +0.33727 -0.122792 0.502389 +0.425945 -0.421811 0.505229 +-0.0462206 -0.209629 0.508153 +-0.509207 0.343755 -0.348851 +0.431696 0.501055 -0.344441 +-0.508812 -0.374248 0.395853 +-0.51424 0.219384 -0.323177 +0.0351007 -0.507036 0.386069 +0.389346 0.497715 -0.24494 +-0.267942 0.346864 -0.513165 +-0.300961 0.368889 -0.515774 +-0.484218 0.300577 -0.483874 +0.451095 -0.34283 0.500822 +0.515075 -0.112747 -0.352148 +-0.307963 0.097483 0.512716 +0.105468 -0.493586 -0.450772 +0.101138 0.134007 -0.492481 +0.455753 0.368532 -0.499867 +-0.307258 -0.326861 -0.51531 +-0.508259 -0.0552982 0.304813 +-0.511203 -0.0875885 0.299608 +-0.497216 -0.40922 -0.168727 +0.452729 -0.497275 -0.266136 +0.241816 -0.439609 -0.486256 +-0.502635 -0.348396 -0.44642 +-0.0518564 -0.445042 -0.490034 +-0.0698578 0.130364 -0.500786 +0.270662 -0.450115 -0.500496 +0.0121696 0.373294 -0.505789 +0.101184 0.348778 0.504183 +-0.06328 0.390982 -0.504788 +0.312168 0.289261 -0.517223 +-0.121469 -0.233012 0.498187 +-0.326503 0.121512 0.50338 +0.504514 -0.0840015 -0.361057 +-0.312312 0.146628 0.512228 +-0.297207 0.123245 0.49492 +-0.295429 -0.506152 -0.380577 +-0.269323 -0.506888 -0.39056 +-0.321243 -0.502942 -0.388252 +0.0700977 0.498007 0.374545 +-0.325695 0.396938 -0.504148 +-0.349284 0.440809 -0.490639 +-0.454919 0.0933691 0.50241 +0.314675 -0.462156 0.485821 +-0.0789658 0.473608 0.469083 +-0.186154 -0.502363 0.16476 +0.510386 -0.324171 -0.305732 +-0.490048 -0.0456034 -0.0721302 +-0.499473 -0.0411789 -0.0397132 +-0.0271654 -0.495101 0.106797 +-0.485325 0.471045 -0.0204713 +0.507277 -0.415513 0.354086 +0.229454 -0.491377 -0.0887568 +-0.0497603 0.181268 -0.50812 +-0.00233884 0.199097 -0.499208 +-0.0572858 0.212608 -0.498177 +0.339119 0.304352 -0.509174 +0.366224 0.10164 0.501296 +-0.107976 -0.26063 0.510798 +-0.0883153 -0.286133 0.511673 +0.375056 0.0693086 -0.512295 +-0.209961 0.514355 0.364825 +0.253591 0.501347 -0.274551 +0.449886 0.488489 -0.0232315 +-0.487078 -0.452405 -0.297627 +0.362052 -0.24383 -0.501365 +-0.413921 -0.059385 -0.49897 +0.373102 -0.211729 -0.509977 +0.341095 -0.22154 -0.510333 +-0.117678 0.0507167 0.502374 +0.505631 0.435114 -0.156226 +-0.0451646 -0.493104 -0.0287932 +-0.0169731 0.210802 0.507754 +-0.303568 -0.148038 -0.510951 +0.421581 0.492594 -0.445339 +-0.452224 0.071257 0.482822 +-0.488811 0.0601558 0.453563 +-0.492128 0.138177 -0.0391721 +-0.485732 -0.153497 0.439528 +-0.49044 -0.145999 0.417871 +-0.501467 0.242632 -0.26063 +0.424192 -0.494649 -0.458093 +-0.509936 0.261814 -0.290166 +0.502734 -0.10012 -0.302121 +-0.5088 0.216081 -0.243951 +0.486907 0.047111 0.444032 +0.509771 -0.240419 0.227476 +0.498395 -0.235798 0.198292 +-0.500134 0.185423 -0.208715 +-0.50617 0.212547 -0.0814497 +-0.186556 0.501111 0.343518 +-0.276418 0.321882 0.505155 +0.0114591 0.444783 0.499344 +0.373616 -0.506008 0.0429552 +0.405437 -0.506851 0.042587 +0.484704 0.348547 0.447763 +-0.510985 -0.40183 0.269544 +0.023844 0.00125808 -0.493404 +0.0142419 0.0326248 -0.505329 +0.202298 -0.48133 -0.467156 +-0.508312 -0.260704 0.106956 +0.479331 0.476393 -0.0468049 +0.509264 -0.39241 0.299865 +0.266534 -0.266655 -0.508197 +0.500321 0.0473958 -0.158936 +0.494535 0.0188439 -0.169805 +0.180983 -0.50953 0.328695 +0.476182 -0.445547 0.446715 +0.172111 -0.501359 0.303771 +-0.26271 0.384052 -0.510952 +-0.225061 0.397865 -0.495268 +-0.507126 0.256196 -0.0973395 +-0.23946 0.324862 -0.510328 +-0.187274 0.324932 -0.510858 +-0.477569 -0.0781867 0.463481 +-0.181474 0.351641 -0.506842 +0.507442 0.143922 -0.435894 +-0.377968 0.400379 -0.496029 +-0.511642 0.286879 -0.209389 +-0.483653 -0.462219 0.404403 +0.116788 -0.507384 -0.123002 +0.0985956 -0.492931 -0.104525 +-0.149876 -0.507088 -0.195306 +-0.179399 -0.50201 -0.198358 +-0.166458 -0.504211 -0.16686 +-0.130674 -0.502097 0.209048 +-0.156698 -0.502584 0.203545 +-0.143929 -0.501652 -0.245216 +-0.132012 -0.505753 -0.218778 +0.261313 0.0962269 -0.499933 +-0.164619 -0.490448 -0.132701 +-0.432165 -0.0761487 0.499236 +-0.435642 0.160472 0.489844 +-0.239643 -0.509238 -0.405376 +-0.187898 -0.486803 -0.452009 +0.492187 0.454793 0.00148661 +-0.511362 -0.245492 -0.0498324 +-0.490821 -0.212375 -0.0589036 +0.307645 -0.00511369 0.50728 +0.0261602 0.497937 -0.236419 +-0.084107 0.504958 -0.162869 +-0.162844 -0.384788 0.509217 +-0.466398 -0.400062 0.472574 +0.503829 0.396712 0.0955677 +-0.183107 0.500997 -0.189769 +0.504492 0.372289 0.245763 +0.315105 -0.214368 0.495501 +-0.489099 -0.0407381 0.454442 +0.109043 -0.499277 -0.179697 +-0.107945 0.508157 -0.139902 +0.0804004 -0.50926 -0.161058 +0.394422 -0.462697 -0.481721 +0.111743 -0.491806 -0.149816 +0.0464698 -0.412151 -0.508545 +0.494121 -0.275111 -0.22152 +0.513055 -0.283686 -0.254476 +0.249443 -0.501503 0.126747 +0.256297 -0.505406 0.158716 +-0.209431 -0.498982 -0.20397 +0.365125 0.346753 0.505848 +0.310602 0.495605 0.0352461 +-0.492466 -0.224863 0.445846 +-0.372261 -0.473605 -0.489024 +0.428174 0.177632 0.492246 +-0.385854 -0.183786 0.499046 +0.394862 0.477533 -0.463139 +-0.415711 -0.174593 0.506906 +-0.494961 0.0984116 0.228164 +-0.494476 0.172842 0.00238029 +-0.499744 0.114206 0.205041 +0.207909 0.490093 -0.457672 +0.0885639 -0.040415 0.490389 +-0.0749538 0.494366 -0.132584 +-0.506006 -0.155636 -0.419923 +-0.216816 0.0724128 -0.500308 +-0.317663 -0.0549078 -0.510279 +-0.196085 0.100871 -0.492125 +-0.505567 -0.142237 0.313995 +0.445286 0.423031 0.484711 +0.356212 0.259568 0.510425 +0.465365 0.164109 0.48107 +-0.287931 -0.0738139 -0.499021 +0.347149 0.307471 0.500679 +0.428667 0.40612 0.499585 +0.377606 -0.338243 0.502149 +0.423027 -0.356105 0.494223 +0.501146 0.212008 -0.190868 +0.505893 0.255575 -0.217 +0.458148 0.487285 -0.439025 +0.05249 -0.509239 -0.0973883 +-0.514247 0.330414 -0.0804362 +-0.510795 0.3043 -0.0963321 +0.395461 -0.504635 -0.0703301 +-0.362004 -0.0115441 0.513412 +0.00376305 -0.353038 0.495911 +-0.356653 -0.0623701 0.509947 +-0.401589 0.496088 -0.033658 +0.506843 -0.0256624 0.117918 +0.508551 0.0720068 0.0812636 +-0.237963 0.49891 -0.17212 +0.50413 0.39307 -0.318332 +-0.510252 0.370608 0.280227 +-0.505185 0.397886 0.273753 +0.394899 -0.505238 -0.428234 +-0.00904911 0.00963603 -0.496029 +-0.204817 0.51153 -0.254161 +-0.0371797 -0.0115937 -0.498598 +0.135232 0.241851 -0.499131 +-0.0728726 -0.499507 0.0714565 +-0.0502116 -0.504421 0.0914571 +-0.0426506 -0.491386 0.0633276 +0.374845 0.499326 0.314217 +0.491636 -0.0411748 0.240243 +-0.477622 0.42976 0.454751 +-0.505966 -0.127173 -0.409541 +-0.498693 -0.0778479 -0.389698 +0.49262 0.197897 -0.429657 +0.486528 0.155937 -0.449243 +0.335073 -0.516426 -0.389687 +0.360097 -0.518659 -0.366485 +0.483253 -0.377438 0.459755 +0.334679 0.00304796 -0.512904 +0.322513 -0.0181639 -0.510908 +0.422814 0.316927 0.504994 +-0.153485 -0.109442 -0.504959 +-0.126702 -0.126038 -0.506228 +-0.503281 0.325633 0.147268 +-0.513499 0.378643 0.141112 +-0.314226 -0.0908365 -0.508403 +-0.502646 0.327222 0.176345 +0.49479 -0.105761 0.0978086 +0.495604 0.392964 0.149635 +-0.292586 0.478455 0.485848 +-0.51296 -0.334939 -0.372177 +0.446075 -0.0882108 0.499158 +0.44505 -0.485635 -0.168446 +-0.501875 -0.100439 -0.221993 +0.477565 0.340074 -0.46509 +-0.504576 0.0628203 -0.258171 +0.329996 0.199843 -0.497355 +-0.510971 -0.409045 -0.403978 +-0.378891 -0.510152 -0.405956 +-0.442857 -0.371199 -0.490771 +0.515232 -0.235791 -0.329227 +0.1832 -0.0664992 -0.506672 +0.50778 -0.425942 -0.323725 +-0.0867368 -0.498237 -0.370302 +0.475094 0.462065 -0.0715158 +0.331883 0.171005 -0.496006 +-0.064237 -0.194167 -0.490477 +0.464835 -0.19363 -0.492531 +-0.0467777 -0.213616 -0.495163 +0.299221 0.181433 -0.512409 +-0.512346 -0.20351 -0.365267 +-0.030463 0.476199 -0.487441 +-0.154206 -0.506104 -0.267427 +0.392416 0.3339 0.51014 +0.295619 -0.505159 0.385232 +-0.442067 -0.489966 -0.443249 +-0.44461 -0.477435 -0.460082 +-0.0714975 0.503205 0.142031 +0.295901 -0.517218 0.355152 +-0.496257 0.428796 -0.168488 +-0.16998 0.425897 0.501778 +-0.0447487 0.14909 -0.50099 +0.410135 0.464088 -0.47216 +-0.0960846 -0.434796 -0.503507 +0.493299 0.0315076 -0.0430278 +0.496713 0.0326303 -0.0142344 +0.473268 0.218773 0.472575 +0.408465 -0.497321 -0.143344 +0.399639 -0.499205 -0.216865 +0.460856 -0.465493 0.455054 +-0.496942 0.0480371 -0.156143 +0.481296 0.454477 -0.351497 +0.424287 0.486661 -0.203709 +0.272367 0.485288 0.443371 +0.270251 0.503692 0.370856 +0.352804 -0.487624 0.446571 +0.389554 0.402522 -0.497037 +0.504412 -0.229571 0.347169 +0.498163 -0.254876 0.319999 +-0.506612 0.243889 0.377727 +-0.494629 0.0950805 0.149305 +0.274545 0.447938 0.500784 +0.322384 -0.502826 -0.113266 +-0.492395 -0.468894 0.233555 +0.46199 0.164381 -0.485008 +-0.336544 -0.398408 -0.513491 +0.507686 -0.332086 -0.0390025 +-0.512739 -0.176659 -0.37907 +-0.0869458 0.210769 0.499268 +-0.0785244 0.24437 0.501173 +-0.0501242 0.221963 0.496727 +-0.0966141 -0.313112 0.495231 +-0.15016 -0.322695 0.495807 +-0.508522 0.374217 -0.353917 +-0.428553 -0.505521 0.40429 +-0.0490322 -0.496935 -0.272852 +-0.486749 0.452413 0.455752 +-0.455498 0.464908 0.468248 +-0.0134513 -0.180419 -0.499493 +-0.2491 -0.491513 0.424931 +-0.498529 0.116415 -0.139299 +-0.433631 0.504016 -0.108163 +0.0622029 0.494973 -0.247759 +0.505169 0.407409 0.382126 +-0.20649 -0.4914 0.21642 +0.441575 0.492738 -0.234658 +-0.430598 0.496862 -0.398879 +0.33519 -0.50031 -0.174668 +-0.182865 -0.506596 0.194773 +-0.211156 -0.501405 0.184651 +0.23657 -0.511333 0.383377 +0.266853 -0.500546 0.36935 +0.503218 0.383869 -0.408917 +-0.47092 0.432955 -0.463604 +-0.0112929 -0.021703 0.492098 +0.237858 -0.51484 0.352196 +-0.50796 0.159889 0.052851 +-0.507549 0.423651 0.27425 +-0.452304 0.458884 0.484563 +0.507062 -0.290593 -0.348378 +-0.115581 -0.495134 -0.243814 +-0.0997668 -0.490576 -0.215045 +-0.46919 0.150855 0.481402 +0.432143 0.493137 -0.0775979 +0.368448 -0.50856 -0.274503 +0.500588 -0.00617177 -0.315196 +-0.500157 0.183105 0.148778 +-0.502378 -0.201547 -0.392898 +0.487097 -0.455924 -0.437458 +-0.447427 -0.00103934 -0.481233 +-0.498051 0.215306 0.156566 +-0.491944 0.174672 0.205952 +-0.50736 0.142933 0.206178 +-0.467448 0.458951 -0.46994 +-0.501275 0.192646 0.179474 +-0.513903 -0.264844 0.289263 +-0.497969 -0.294209 0.280039 +-0.496542 -0.274462 0.264562 +-0.486164 -0.447825 0.289258 +-0.459879 -0.493127 -0.43262 +-0.502798 0.0360651 -0.187662 +-0.508648 0.0194327 -0.21641 +0.230979 0.25295 0.493789 +0.490897 0.0589756 -0.0292117 +0.0213645 -0.491135 -0.161424 +0.289763 -0.496422 -0.185522 +0.305589 -0.51234 -0.166234 +-0.509746 0.00343584 -0.189521 +-0.507262 -0.0142624 -0.166555 +0.222347 -0.503684 0.0433906 +0.475319 -0.470781 0.0713649 +0.220167 -0.492549 0.0755449 +0.43667 -0.499882 0.104075 +0.426093 -0.505572 0.132227 +0.367597 -0.503031 0.145956 +0.265172 0.17516 -0.496429 +0.236093 0.169939 -0.493478 +0.253117 0.147059 -0.509766 +-0.400997 0.504696 0.316274 +0.430993 0.180029 -0.503627 +0.406581 0.245547 -0.512555 +0.21123 0.17833 0.508852 +-0.355389 0.514632 0.30502 +0.19785 -0.473054 -0.484365 +-0.409838 0.501756 0.287246 +-0.0175253 0.456285 -0.487655 +-0.215296 0.129267 0.504731 +-0.184229 0.131696 0.50133 +-0.198221 0.103124 0.499474 +-0.46742 -0.491061 -0.252544 +-0.492251 -0.367961 -0.459977 +-0.492965 0.0968941 -0.207605 +-0.507739 0.0911123 -0.241539 +-0.456317 -0.395139 -0.494362 +-0.182104 0.0716887 -0.493295 +-0.414154 0.496595 0.461497 +0.504583 0.0744625 -0.146546 +0.491816 0.0997426 -0.130973 +-0.0646471 -0.507559 -0.133285 +0.390422 -0.256389 0.508608 +0.404942 -0.282093 0.511029 +-0.209084 0.497386 -0.416822 +-0.014734 0.484665 -0.472655 +0.0917649 -0.499213 -0.131148 +-0.392903 -0.0826388 0.49708 +-0.400709 -0.041276 0.49629 +-0.440183 -0.498811 -0.159385 +-0.438286 -0.489178 -0.133909 +-0.49164 -0.174202 0.195842 +0.483407 -0.327807 -0.46022 +0.308208 0.255275 -0.497533 +0.335486 0.232411 -0.497525 +0.256086 -0.370673 0.501182 +0.478953 0.481875 0.352725 +-0.475371 -0.483809 -0.23112 +-0.317702 -0.39579 0.513426 +-0.218658 0.501589 -0.394884 +-0.422468 -0.500397 -0.0761173 +0.0241002 -0.497318 0.0175828 +0.0542509 -0.506451 0.0235032 +-0.450415 -0.0572623 0.490895 +-0.472152 0.108842 0.490596 +-0.509807 -0.166082 0.223944 +0.503274 0.209331 -0.372419 +-0.489732 0.449226 -0.170636 +-0.454752 0.168087 0.484252 +-0.459776 0.189657 0.484167 +0.135102 0.298871 -0.497611 +-0.495113 -0.143874 -0.18425 +-0.477827 0.158651 0.46363 +-0.509758 -0.238063 -0.204192 +0.0242734 -0.427218 0.490246 +-0.124392 0.0869657 0.499241 +-0.12863 0.121087 0.502071 +-0.0972826 0.109876 0.500798 +0.445007 0.496759 -0.315502 +-0.221832 0.358755 0.512082 +-0.173888 0.339416 0.500573 +-0.50781 0.106048 -0.049943 +-0.507921 0.0809778 -0.027845 +-0.501311 0.0736676 -0.0601634 +0.416203 0.510777 0.000379014 +0.505816 0.435552 -0.183426 +0.22619 0.447348 -0.499152 +-0.213794 -0.500945 -0.449026 +0.0594959 -0.464114 0.492075 +0.111149 0.286303 -0.503621 +0.148983 -0.423424 0.493375 +-0.428275 0.481565 -0.455161 +-0.508044 -0.180166 0.168046 +0.138733 -0.405524 0.493401 +-0.300716 -0.26908 -0.496988 +0.0355891 0.50846 -0.267067 +-0.350692 0.509336 -0.433381 +0.439436 -0.382241 -0.498105 +-0.501509 0.0165471 -0.357184 +-0.421083 -0.492303 0.20025 +-0.509652 -0.331171 0.18375 +-0.451188 -0.490377 0.205954 +-0.43226 -0.495912 0.232866 +-0.314475 0.492889 -0.468091 +0.2944 0.43785 -0.495856 +0.369938 -0.50532 0.0975088 +-0.499863 -0.419968 -0.112651 +-0.491408 0.136375 0.075446 +-0.489351 0.436926 0.401073 +0.135846 0.156931 0.490482 +-0.463146 -0.479425 -0.469802 +0.417195 -0.49889 0.162209 +0.195643 0.152375 0.509231 +0.190837 -0.167638 -0.505831 +0.090148 -0.474327 0.459026 +0.178574 0.125548 0.508399 +0.31739 0.401977 -0.51152 +-0.507914 0.413672 0.178661 +0.0984753 -0.413718 0.508793 +0.41702 0.506265 -0.319755 +-0.435648 -0.283181 0.496059 +-0.108703 0.489215 -0.426122 +-0.409511 -0.16702 -0.493328 +0.091755 0.307949 -0.499715 +-0.494932 -0.203279 -0.285227 +-0.438939 -0.312205 0.490915 +-0.494243 -0.15954 -0.244294 +0.423954 -0.492627 -0.268319 +0.399704 -0.507665 -0.27217 +0.479733 0.460961 0.445987 +0.411585 -0.497893 -0.243416 +0.051793 -0.415328 0.497707 +0.0744832 -0.402419 0.494381 +0.361449 0.321055 -0.512981 +-0.477579 0.0601849 -0.464049 +0.387166 0.342142 -0.507663 +0.353192 0.349117 -0.503621 +-0.356241 0.172858 0.508955 +-0.501578 0.349886 -0.432697 +-0.504584 0.353885 -0.377868 +-0.496831 0.334907 -0.456383 +0.483023 0.0641811 0.463963 +-0.156797 -0.504412 -0.0439322 +0.50994 -0.38261 0.0316057 +0.4972 -0.0193774 -0.0113116 +0.505172 0.00829688 0.00229433 +0.125043 -0.503007 0.127861 +0.493198 0.01161 -0.204081 +0.491861 0.451134 0.198296 +0.112013 -0.49981 0.104017 +-0.147923 -0.176077 -0.505189 +-0.156028 -0.144916 -0.508514 +-0.191717 -0.182878 -0.500899 +-0.450179 0.489436 -0.443884 +0.504537 0.337861 -0.379635 +0.509843 0.388711 -0.353514 +-0.490706 -0.163967 -0.161963 +-0.498499 -0.184022 -0.110446 +-0.503354 -0.212722 -0.125594 +0.507848 -0.273651 0.243615 +0.343984 -0.371593 -0.517254 +0.513474 -0.264623 0.280804 +0.11999 -0.506927 0.431758 +0.374238 0.184579 -0.514576 +0.363766 0.136236 -0.505966 +0.390336 0.125419 -0.497976 +-0.498352 0.104866 0.0667146 +-0.504525 0.0732828 0.0585682 +-0.0650502 -0.0678758 0.507236 +0.0278607 -0.490653 -0.132242 +0.497647 -0.157408 0.370732 +-0.405819 0.505321 0.214173 +-0.491519 0.0143604 -0.454202 +-0.420358 0.506506 0.187982 +0.271399 0.241142 -0.501975 +0.249998 0.219152 -0.510742 +0.504813 -0.00677104 -0.290286 +0.272766 0.205549 -0.494741 +-0.0248324 0.491663 -0.0184156 +-0.276121 -0.498994 0.28356 +-0.2271 -0.507528 0.310999 +-0.485495 0.473713 0.205641 +-0.151514 0.363544 0.497013 +0.467019 -0.47389 -0.343519 +-0.23972 -0.499003 -0.452175 +-0.0657404 0.456741 -0.488247 +0.510793 0.107029 0.333336 +-0.269091 -0.510868 -0.220704 +0.210051 0.46362 -0.492656 +0.502398 0.175724 -0.2951 +-0.0401762 -0.425529 -0.499672 +-0.00748346 0.505813 0.0433708 +0.489678 -0.442346 -0.251801 +0.196637 0.445399 -0.493199 +-0.444173 0.499462 0.0927033 +-0.327891 -0.512136 0.145387 +0.337767 0.512382 0.274167 +-0.495119 -0.406007 -0.0249715 +-0.0120597 -0.494601 -0.444579 +-0.501589 -0.0932507 0.028368 +-0.494702 -0.0958889 -0.0020036 +0.318127 0.507766 0.0590242 +0.0342304 -0.494772 0.0464142 +0.33171 0.513404 0.240461 +0.0145712 -0.500381 0.0691397 +-0.210709 -0.508869 0.359885 +0.503653 -0.0238905 -0.430721 +-0.197049 -0.0205334 0.492159 +-0.496071 0.357329 0.453337 +-0.511346 -0.310782 -0.194513 +-0.500536 -0.285906 -0.247422 +0.0247433 -0.428098 -0.494001 +-0.449275 0.444312 -0.487485 +-0.243772 0.462171 -0.48381 +-0.499673 0.399625 0.432456 +0.217226 0.506531 0.361096 +0.211516 0.425902 -0.505527 +0.242767 0.422773 -0.496212 +-0.501959 0.134768 -0.322845 +-0.50626 0.140938 -0.287939 +-0.509647 -0.370247 0.0571793 +-0.441886 0.0682018 0.505573 +-0.500795 -0.403063 0.00902614 +-0.320923 0.501741 -0.354215 +0.158125 -0.314915 -0.502483 +0.00844726 0.494372 -0.0119194 +0.51582 -0.336732 0.237359 +-0.472552 0.0159419 -0.464869 +-0.173151 0.497734 -0.158892 +-0.172111 0.421658 -0.502708 +-0.445816 -0.494497 -0.100687 +-0.344175 -0.508734 0.018904 +-0.499612 0.200063 0.293542 +-0.483683 0.103983 -0.479299 +-0.455243 0.489023 0.03781 +0.498831 0.393618 0.451679 +-0.455803 0.490167 0.0679169 +0.105208 0.024795 -0.494398 +-0.508449 0.218909 -0.00506474 +0.471882 -0.470788 0.038786 +-0.267303 -0.493923 0.196291 +-0.241207 -0.494306 0.17379 +-0.494631 -0.450771 0.21075 +-0.234481 0.361415 -0.511815 +-0.169683 -0.428577 -0.498887 +-0.484297 0.44207 -0.143207 +-0.495609 -0.148096 0.0103008 +-0.145441 0.0267218 0.496571 +-0.464079 0.480631 -0.128314 +-0.508637 -0.401861 0.384931 +0.464863 0.471099 0.108568 +0.499345 0.0241541 0.330606 +-0.141112 0.501213 -0.149204 +0.499974 -0.176131 -0.0132206 +0.49664 -0.210601 -0.0174723 +0.430998 -0.48744 -0.405765 +0.37288 0.512839 0.362504 +0.00352408 -0.444691 -0.486749 +0.494466 -0.243627 -0.0257694 +-0.492818 -0.0106593 0.196704 +0.498036 0.450748 -0.169611 +-0.420362 -0.507283 0.0121417 +-0.412232 -0.506947 -0.0425591 +0.450839 0.0578097 0.480551 +-0.149938 0.505579 -0.181198 +-0.497601 -0.218376 0.238419 +-0.510583 -0.148219 0.282727 +-0.151534 -0.264098 -0.499243 +-0.42265 -0.140427 -0.499152 +0.355222 -0.503242 -0.446671 +-0.254831 -0.38555 -0.508893 +-0.260325 -0.418511 -0.502665 +0.205977 -0.24743 -0.510486 +-0.448768 0.348742 -0.490749 +-0.454966 -0.484977 0.242952 +-0.280389 0.101989 0.502395 +0.145282 -0.288215 -0.50221 +0.193925 -0.289227 -0.50671 +-0.0952359 -0.506627 -0.183741 +0.171971 -0.28889 -0.511435 +-0.176995 0.205635 0.496853 +0.507593 -0.0215235 0.172749 +0.397209 0.0516797 0.496006 +-0.438576 -0.116751 -0.503887 +-0.235516 0.499087 0.202871 +-0.474304 0.472296 -0.246271 +0.364202 0.0286915 0.514718 +0.41304 0.493298 -0.103263 +0.506035 -0.261452 -0.19248 +-0.409169 -0.114496 -0.493547 +-0.49979 0.322728 -0.0249612 +0.313284 0.509168 0.298125 +0.487304 -0.473092 0.282928 +-0.024721 -0.496718 -0.363188 +0.0243361 -0.507851 -0.338444 +-0.510841 0.352683 -0.15827 +-0.501506 0.332592 -0.108503 +-0.508492 0.381302 0.38518 +-0.265588 0.0647623 -0.494877 +0.217121 0.507422 -0.1067 +0.0441745 -0.495973 0.0750639 +0.0551639 -0.506525 0.103756 +-0.252199 0.110549 -0.499862 +0.495277 -0.0440575 -0.0269066 +0.493154 -0.0634082 -0.0459556 +0.148328 -0.476022 -0.479597 +0.505277 -0.0735085 -0.0183824 +0.302646 0.219011 -0.507632 +0.437539 -0.498827 -0.288723 +-0.246857 0.490105 -0.459888 +0.433737 -0.309972 -0.503071 +0.430631 -0.214481 0.505108 +-0.315691 0.0327522 0.505222 +0.470528 0.485013 -0.0685511 +0.218499 -0.069135 -0.507107 +0.496997 0.461395 -0.0486407 +0.254098 -0.0699097 -0.494107 +0.237987 -0.0388387 -0.507645 +-0.299564 -0.494885 -0.0653281 +0.483827 0.169829 -0.474284 +0.48868 0.201792 -0.472835 +0.0591005 0.325983 0.501681 +-0.242024 0.0608049 -0.497582 +-0.500913 0.416052 0.448503 +-0.17873 -0.123861 0.497402 +-0.15165 -0.101016 0.508766 +0.275912 -0.412041 -0.50892 +0.281435 -0.386456 -0.51172 +0.26428 -0.274764 0.504649 +-0.358996 -0.516511 -0.285617 +0.319635 -0.424676 -0.503261 +-0.319062 0.0662526 0.510341 +-0.338305 -0.514982 -0.338611 +0.467298 0.470671 -0.0924249 +-0.357708 0.49679 0.0936519 +-0.371062 0.410095 0.511314 +-0.39402 0.449138 0.501833 +-0.107596 -0.244053 -0.507415 +0.153523 -0.499674 0.132769 +0.111448 -0.496998 0.145383 +-0.327388 0.315678 -0.508829 +0.466039 0.123845 -0.471768 +0.136187 -0.494517 0.180498 +0.491525 0.259944 0.104876 +0.49075 0.465266 -0.096799 +0.492033 -0.0188095 0.0196348 +0.509051 -0.0501776 0.0688243 +-0.122712 -0.512901 0.353243 +-0.366961 -0.315703 -0.517088 +-0.409445 -0.438278 -0.487414 +-0.482885 0.0715921 0.473603 +-0.335702 -0.01138 0.512775 +0.429955 0.489142 0.435835 +-0.3452 0.0160384 0.496723 +0.180849 0.179272 0.505583 +0.15943 0.257241 -0.506012 +0.441212 0.444665 0.475398 +0.19785 -0.103022 -0.500117 +-0.49926 -0.0250563 0.16945 +-0.500733 -0.041212 0.194275 +0.230607 0.498465 -0.0536341 +-0.495103 -0.29338 0.183048 +-0.500343 -0.280039 0.218226 +-0.497585 -0.314216 0.213866 +-0.392042 0.497165 0.0907757 +0.152074 -0.4977 -0.211484 +-0.0722444 -0.489176 0.426451 +0.122537 -0.491587 -0.251878 +0.0822788 -0.179241 -0.494437 +-0.480185 0.0977326 0.472012 +-0.093377 -0.482699 0.462029 +-0.016915 0.0724962 -0.504253 +-0.503359 -0.0790043 -0.241977 +0.00794115 0.060773 -0.503808 +0.29953 0.0589046 -0.508223 +0.124321 -0.497359 -0.0984753 +0.141091 -0.505378 -0.0262454 +-0.132329 0.491909 0.462135 +-0.374009 0.501082 0.146129 +0.152893 -0.491064 0.459985 +-0.504292 0.0577634 -0.124417 +-0.489969 0.0908758 -0.11539 +-0.501382 0.0661069 -0.0924283 +0.211977 0.115519 -0.491869 +0.194276 0.141505 -0.491382 +-0.479235 -0.321306 -0.472212 +-0.348843 -0.134511 0.512561 +-0.344021 -0.088909 0.498597 +0.0893786 0.316009 0.512944 +0.124126 0.324335 0.50126 +0.506926 0.300441 0.16499 +0.498595 0.283363 0.123348 +-0.263953 -0.21576 -0.501037 +-0.0335297 -0.490285 -0.0858234 +0.479772 0.344583 0.469969 +0.454291 -0.491731 -0.298326 +0.0912827 0.21055 -0.498147 +0.305411 -0.507083 -0.290664 +0.273923 -0.507881 -0.300006 +-0.505235 -0.0215798 0.410943 +-0.237267 -0.201147 -0.491735 +0.32243 0.429674 -0.509486 +0.31985 0.449908 -0.488663 +-0.476641 -0.476554 0.253316 +-0.418647 -0.303084 0.507353 +-0.207079 -0.416246 0.494202 +-0.225747 0.448466 -0.484318 +-0.203107 0.458714 -0.488239 +-0.0718081 -0.0958144 -0.505903 +-0.047398 -0.114106 -0.496837 +-0.00992521 -0.463437 0.476074 +0.49737 -0.055163 0.437121 +0.0699879 -0.340048 0.503099 +-0.506552 0.429584 -0.353503 +-0.154212 0.441145 -0.500244 +-0.501702 -0.0473736 0.247996 +-0.496297 -0.0669342 0.27393 +-0.498923 -0.430829 -0.165756 +-0.504359 -0.078062 0.243024 +-0.46558 0.273483 -0.47756 +0.503291 -0.438771 0.0911955 +0.501873 0.32927 -0.0258379 +0.503695 0.291096 -0.25168 +-0.130717 0.494849 0.0306961 +-0.12247 0.496657 0.0649042 +-0.0116614 0.454906 0.499072 +-0.232593 -0.236905 -0.508524 +-0.443453 0.320775 0.500454 +0.502671 0.320687 -0.404485 +0.182488 0.463391 -0.480958 +-0.260168 -0.227641 0.502643 +-0.26276 -0.193818 0.500292 +-0.317599 -0.501198 -0.115893 +-0.510883 0.229483 -0.293746 +0.463589 -0.114575 -0.469072 +-0.344175 -0.495508 -0.12389 +-0.285753 0.231019 0.512891 +0.110924 -0.220134 0.4916 +-0.427134 0.498689 -0.0269961 +0.320824 0.180045 0.509994 +0.253827 0.499966 -0.114526 +-0.394832 -0.439832 0.500948 +-0.494385 -0.299615 -0.442082 +0.50308 0.437173 0.0822488 +-0.491405 0.135579 -0.449932 +0.516199 0.337962 -0.236804 +-0.0303158 -0.368853 0.501047 +0.502383 0.116315 -0.056815 +0.499516 0.142356 -0.0697699 +-0.514878 -0.408701 0.356279 +-0.399413 0.225863 -0.510914 +0.501215 -0.299864 0.143876 +-0.435491 0.00758292 0.492407 +-0.0396821 0.0232363 -0.493284 +0.474329 0.36403 0.480894 +-0.041708 0.0555794 -0.503689 +0.485281 0.439008 0.111599 +-0.502172 -0.225845 -0.261456 +-0.12844 -0.499025 0.000928538 +-0.307727 0.159965 -0.501476 +0.505665 0.04984 -0.131674 +-0.152492 -0.226174 0.509308 +0.507612 -0.00742113 0.278564 +0.0026579 -0.0928935 0.492845 +0.49307 0.455396 0.14328 +-0.504974 -0.0656456 0.0132076 +-0.501508 -0.387128 0.334119 +-0.503664 -0.03663 -0.00558407 +-0.502138 -0.443579 0.319391 +-0.492895 0.455897 0.019194 +-0.168798 0.243839 -0.500159 +-0.483815 -0.393495 -0.461046 +-0.17507 0.301275 -0.501504 +-0.220477 0.263837 -0.508516 +0.13702 -0.490949 -0.115772 +0.40392 0.510648 -0.397623 +-0.50458 0.00604552 0.169518 +-0.419736 0.498238 -0.0558056 +0.326738 -0.150279 -0.503553 +0.502166 -0.317936 -0.267786 +0.506374 -0.349255 -0.28008 +0.50119 -0.345449 -0.247622 +-0.489608 -0.296386 -0.464128 +-0.50967 -0.184149 0.38394 +-0.503719 -0.227555 0.382232 +0.455544 -0.483758 0.145569 +-0.497999 -0.431446 0.350826 +-0.336172 0.178479 -0.50411 +-0.484744 0.465238 -0.190128 +0.175742 -0.48569 -0.472138 +-0.241809 -0.134938 0.507757 +-0.50875 -0.328653 0.351514 +0.218206 -0.416982 0.507067 +0.112861 -0.445043 -0.491776 +0.0617193 -0.111014 -0.502421 +0.087516 -0.108827 -0.500885 +0.395828 0.499121 -0.215736 +0.434628 0.266512 -0.505313 +-0.46743 -0.475643 -0.361793 +0.310774 -0.110871 0.495964 +0.497336 -0.13851 0.437738 +0.509379 0.339213 -0.0777019 +-0.129874 0.204183 -0.49763 +-0.25906 0.188589 -0.509941 +0.240301 -0.34718 -0.506263 +0.498746 -0.152483 -0.136 +0.50397 -0.178629 -0.147761 +0.493367 -0.177527 -0.118717 +-0.164665 -0.480543 0.480871 +0.212334 -0.500066 -0.329381 +-0.368831 -0.42806 -0.502147 +-0.377766 0.501371 0.216485 +0.208033 -0.503071 -0.299459 +-0.49679 -0.00453532 0.364702 +-0.497447 -0.0539852 0.355486 +-0.51232 -0.0132761 0.336892 +-0.0487262 -0.379481 -0.500923 +-0.104655 -0.389761 -0.504086 +-0.0864825 -0.409498 -0.497698 +-0.0432403 0.117158 -0.509347 +-0.0682398 0.10056 -0.497448 +-0.042578 0.0863653 -0.49129 +0.183967 -0.200928 0.498814 +-0.183072 -0.500091 -0.341845 +0.221824 -0.168154 0.502291 +0.189766 -0.364482 -0.498145 +-0.513323 0.343255 0.408142 +-0.370117 -0.513937 0.00364755 +0.502583 0.447886 -0.0252272 +0.495573 0.420983 0.365843 +-0.053967 -0.491038 -0.199481 +-0.0775744 -0.498911 -0.199493 +-0.0692332 -0.504334 -0.177751 +0.481972 0.462867 -0.166033 +0.489516 0.240303 -0.44957 +0.444319 -0.0467747 -0.485381 +-0.210657 0.0361046 0.509145 +-0.24341 0.0812529 0.493048 +-0.205182 0.0558119 0.498166 +0.35864 -0.47012 0.493991 +-0.497738 0.232192 0.105877 +0.484052 0.474972 0.161552 +-0.406314 -0.39767 -0.499093 +0.162147 -0.430952 -0.503744 +-0.0812046 0.507291 0.435885 +0.00755072 -0.284324 0.498494 +-0.021454 -0.299124 0.506471 +0.500124 -0.343032 0.113279 +0.510581 -0.359047 0.0578677 +0.114708 0.290805 0.511432 +0.119138 0.233593 0.495411 +-0.154136 0.0130625 -0.492608 +-0.166216 0.0424981 -0.509121 +-0.130072 0.504896 0.250945 +-0.0250468 0.488133 -0.450628 +0.461125 0.0327772 -0.485831 +0.0908719 -0.510884 0.389776 +-0.414019 -0.27967 -0.496388 +-0.437512 -0.441692 -0.491947 +-0.221187 0.420135 0.506757 +-0.370526 -0.447992 -0.489489 +0.138991 -0.507788 0.360897 +0.252851 0.0658532 -0.495738 +-0.171066 0.507986 0.136648 +0.231263 0.0902413 -0.491787 +0.47097 0.356124 -0.484458 +0.264316 -0.495794 -0.222485 +0.404274 -0.0862497 0.493506 +0.427402 -0.0740413 0.503839 +-0.4943 0.389909 0.45025 +-0.121693 -0.372947 -0.51276 +-0.0793196 -0.331711 -0.495519 +0.195768 0.401619 -0.502125 +0.211034 0.375343 -0.497158 +-0.506741 -0.0674157 0.0457773 +0.350137 -0.0150928 -0.503518 +0.375471 -0.0115766 -0.502622 +-0.501483 0.236611 -0.22817 +-0.508949 -0.401893 -0.341517 +0.481603 -0.453034 0.0835513 +0.241659 0.498565 0.12417 +-0.498511 0.247502 0.45613 +-0.474275 -0.0669936 -0.465321 +-0.19674 0.499506 0.262179 +-0.306855 0.380575 0.508838 +-0.279295 0.391966 0.508781 +0.339345 0.357996 0.520177 +0.337852 0.380834 0.507564 +0.361011 0.37435 0.515402 +0.443449 -0.0175084 -0.493607 +0.25692 0.485025 -0.448369 +0.498063 -0.0526624 -0.45968 +0.489782 0.436419 -0.0493117 +0.219685 0.190624 -0.497076 +0.244574 0.195603 -0.510218 +0.188326 0.223067 -0.493875 +-0.122317 0.512139 0.301655 +-0.452627 -0.348253 -0.486715 +-0.0724367 -0.287695 -0.496878 +-0.4228 -0.333336 -0.507001 +-0.45734 0.21426 0.493309 +-0.0815388 -0.244404 -0.492864 +-0.0920124 0.507329 0.299762 +-0.107305 -0.326653 -0.497037 +0.495888 -0.194738 -0.256303 +0.504383 -0.226193 -0.266634 +-0.471144 0.477647 0.227015 +0.503088 -0.220515 -0.236776 +-0.49592 0.338749 -0.184281 +0.28161 0.0154463 -0.496562 +-0.0676692 0.00491616 -0.503608 +0.503699 -0.323735 -0.0695649 +0.494369 0.30445 0.141219 +0.508697 0.0705185 0.175653 +-0.484694 0.380584 0.472118 +0.258539 -0.00962771 -0.50472 +0.292004 -0.0150465 -0.505534 +-0.415248 -0.430682 0.502524 +-0.436092 0.420287 -0.482458 +-0.504032 0.210835 0.376928 +-0.435139 -0.491062 -0.0428383 +-0.498001 0.249413 0.406817 +-0.498602 0.0689815 0.229025 +-0.500674 0.0531986 0.262047 +0.239917 -0.500862 -0.0440909 +0.260077 -0.498671 -0.002713 +0.5064 0.415375 -0.366193 +0.503624 -0.372457 0.096509 +0.501064 -0.409646 0.094319 +0.471347 0.486011 0.199813 +0.495063 0.238988 -0.261753 +0.285418 0.422741 0.495791 +0.0143301 -0.514406 0.336268 +0.234014 -0.422552 -0.507551 +0.248771 -0.376162 -0.502922 +0.202104 -0.497673 0.308816 +-0.43464 -0.163113 -0.491902 +-0.147758 0.510079 0.303597 +0.0773202 0.506464 0.398994 +0.435716 -0.495493 -0.241912 +-0.409207 -0.273079 0.493991 +0.013359 -0.500854 -0.402747 +-0.49626 -0.449823 0.0453819 +0.0734067 -0.493879 -0.405029 +0.501141 -0.0350298 -0.306984 +0.503828 -0.0783221 -0.259981 +0.503193 0.13459 -0.169933 +-0.512225 -0.166151 -0.280382 +-0.096505 0.497298 -0.108688 +-0.160135 0.503605 0.11319 +0.496842 0.0963629 -0.193529 +0.33031 0.498782 0.447771 +-0.512257 0.104275 -0.337229 +-0.504847 -0.0494545 -0.103237 +-0.492296 -0.0792246 -0.121827 +0.165102 -0.49726 -0.0220393 +0.494311 0.221783 0.407751 +0.50379 0.114772 0.424283 +0.31101 0.373315 0.516242 +-0.176538 -0.0600311 -0.501276 +-0.252875 -0.490193 -0.460625 +0.503154 0.20209 0.435592 +-0.476802 -0.298086 0.480315 +-0.451797 0.11819 -0.493002 +0.0968317 0.499704 -0.4426 +-0.476959 0.274972 -0.463826 +0.0632366 -0.48 0.476198 +-0.433724 -0.486608 0.174502 +-0.440297 -0.502687 -0.254558 +-0.489858 0.301504 -0.457281 +-0.0753106 0.496897 -0.429608 +-0.120919 -0.475409 -0.483312 +-0.486081 -0.472545 -0.316599 +0.180177 0.488797 -0.446067 +-0.185323 -0.455064 -0.498017 +0.0827356 -0.437402 -0.487371 +0.137027 0.0247922 -0.50692 +0.502802 0.298818 -0.429999 +-0.307775 -0.501652 0.32378 +0.448545 0.485957 -0.256996 +-0.34826 -0.505683 0.372855 +-0.22046 0.500877 0.123347 +-0.106882 0.198952 -0.509523 +0.170833 0.037321 0.494623 +-0.0650388 0.243437 -0.497021 +-0.492261 -0.0497334 -0.128326 +0.238303 -0.50943 -0.342627 +0.119939 0.495767 0.426366 +-0.507899 -0.0329933 -0.146057 +-0.49775 0.0596232 -0.429624 +-0.485603 0.0357972 -0.439172 +0.500452 0.163092 -0.0573693 +0.497386 0.143395 -0.0109506 +-0.510168 -0.369922 0.180769 +-0.49872 -0.332817 0.239836 +-0.0269153 -0.491754 0.136234 +0.391476 -0.309322 0.512611 +-0.507807 0.407825 -0.121306 +-0.503074 -0.327364 -0.342666 +-0.502162 0.00580887 0.0415908 +-0.49531 -0.0321932 0.0330688 +-0.0390047 -0.187557 -0.50181 +0.399445 -0.503565 -0.112381 +0.0949808 0.496328 0.376592 +0.498532 -0.0786219 -0.450221 +0.0871434 0.285186 0.501549 +-0.476237 -0.326092 0.469233 +-0.50364 0.112686 0.0973748 +-0.498329 0.352739 0.226682 +-0.505539 0.249085 -0.31843 +0.509465 0.0361306 0.126654 +0.14802 0.498084 -0.18639 +0.0365806 0.475385 -0.457767 +-0.474037 0.329986 -0.491873 +0.387779 0.365015 0.51102 +0.326582 -0.505544 0.314807 +0.359395 -0.500245 0.26463 +-0.204716 -0.496094 -0.0410264 +-0.182078 -0.503954 -0.056289 +0.496168 0.0123484 -0.334429 +-0.509353 -0.107871 -0.307115 +-0.22354 -0.504709 -0.0521122 +0.50568 0.0245172 -0.392096 +-0.491399 -0.308732 0.436734 +0.279067 -0.500675 0.427729 +0.506113 -0.137685 -0.266938 +0.224816 0.365263 0.50223 +-0.405276 -0.350707 0.501795 +-0.50065 0.163155 -0.188549 +-0.456164 -0.292489 0.48866 +0.117957 -0.509865 0.403387 +-0.227583 0.248852 0.508899 +-0.490252 0.140772 -0.164442 +-0.233862 0.503693 -0.350843 +0.136167 0.507931 -0.149857 +-0.507306 -0.0960387 -0.158278 +-0.50369 -0.116433 -0.12822 +-0.494087 -0.118214 -0.179029 +0.347882 -0.512747 0.338561 +-0.513723 -0.380696 0.3652 +0.0816193 -0.450233 0.496137 +-0.5075 -0.326313 -0.0626609 +0.499136 0.173606 -0.387824 +-0.29014 0.513873 -0.341311 +-0.506479 -0.376921 -0.0104274 +-0.503126 0.413855 -0.438863 +-0.463732 -0.263206 -0.473949 +-0.500311 -0.442507 -0.124886 +-0.496 0.404457 -0.408481 +-0.244364 -0.462029 -0.489943 +0.487723 0.468545 0.301443 +-0.509615 -0.114522 0.0403516 +-0.499159 -0.158475 0.0653174 +0.402955 -0.413128 0.500889 +-0.0234356 -0.495065 0.414839 +-0.0549619 -0.510765 0.410082 +-0.0468994 -0.490953 0.432033 +-0.501364 -0.271369 0.0833625 +-0.496569 -0.291572 0.0191429 +-0.503885 0.0817972 -0.148366 +0.513339 -0.387744 -0.0453893 +-0.518687 -0.358962 0.343202 +-0.178909 0.466192 -0.485222 +-0.510953 0.154089 0.26855 +-0.0141963 0.0423862 -0.495851 +-0.14206 -0.290085 -0.502694 +-0.421155 -0.463428 -0.491517 +-0.127554 -0.348242 -0.495216 +-0.106071 0.287086 0.507728 +-0.256722 0.417268 -0.50133 +-0.04722 0.139138 0.505841 +-0.251369 0.443825 -0.494411 +-0.282055 0.433834 -0.490003 +-0.424894 -0.0323428 -0.4894 +-0.0867241 -0.497071 -0.292394 +0.123918 0.50403 0.15314 +0.210467 0.312241 0.514252 +-0.493974 0.157009 0.174784 +-0.06443 -0.50314 -0.288998 +0.171426 0.492809 -0.156078 +-0.322214 -0.280769 -0.517179 +0.498248 -0.246912 0.0929043 +0.494392 -0.232399 0.110914 +-0.505868 -0.260398 0.320354 +-0.271597 0.291296 0.5112 +-0.505301 -0.297007 -0.325231 +-0.497418 0.0256544 -0.132433 +-0.508211 0.0031118 -0.110876 +-0.505221 -0.00474316 -0.139604 +0.494619 0.353703 -0.451857 +-0.144005 0.485633 -0.467598 +0.453337 -0.397834 -0.495448 +-0.385526 -0.281553 -0.507089 +-0.0105273 -0.494991 -0.228055 +0.335776 0.284879 0.510939 +0.0936038 -0.152343 0.50562 +-0.107205 0.462299 0.49145 +0.502285 -0.276235 0.0995092 +0.510153 -0.282063 0.0487246 +0.503721 -0.309336 0.111673 +0.228316 0.0979189 0.509525 +-0.456919 -0.433635 -0.491121 +-0.0414782 -0.513925 -0.332146 +0.0783098 0.459007 0.474838 +-0.243148 0.456302 0.495264 +-0.0161017 -0.497023 -0.308771 +-0.370151 -0.515265 0.345396 +0.502029 0.118007 -0.4301 +-0.500052 -0.419001 -0.359205 +0.496685 -0.0193446 -0.0391267 +0.506705 0.00412534 -0.0549103 +0.497009 -0.0227781 -0.065793 +0.248006 0.270241 -0.507622 +0.259373 0.301127 -0.496445 +0.228524 0.296458 -0.510947 +0.503161 -0.304671 -0.0145102 +0.383099 -0.0725413 0.501633 +0.424893 -0.184214 0.492504 +0.227888 0.497433 0.0283571 +0.228521 0.492797 0.0793288 +0.509042 -0.292907 0.0194626 +0.224232 0.0142388 0.490907 +0.208963 -0.0191153 0.506415 +0.153325 -0.405221 -0.498071 +-0.265426 0.503121 -0.360867 +0.0954636 -0.394559 -0.501551 +0.452194 -0.479526 -0.194719 +0.474808 -0.487425 -0.0361153 +-0.0702523 -0.507523 -0.111172 +-0.458181 0.144147 0.500178 +-0.274486 -0.465999 0.481393 +0.495571 0.0246857 0.458494 +-0.297377 0.0708268 -0.504851 +-0.482332 -0.449302 -0.44497 +-0.294763 0.105055 -0.511562 +-0.501502 -0.382182 0.217587 +-0.503536 -0.291458 0.111315 +-0.339656 0.0945983 0.51023 +-0.512186 -0.290745 0.146917 +-0.130269 -0.431372 0.505575 +-0.497195 0.388897 -0.227659 +-0.397308 -0.424211 -0.508281 +-0.497471 0.412881 -0.235965 +-0.505797 0.418081 -0.192902 +-0.257964 0.513869 -0.329714 +0.263445 0.0940861 0.492708 +0.239504 0.0470319 0.494668 +0.215164 0.0709701 0.493015 +0.454699 0.369323 0.484781 +0.500595 -0.125238 -0.0418888 +0.495319 -0.141556 -0.0132146 +0.489959 -0.106971 -0.0140774 +0.507372 -0.401448 -0.307382 +0.193856 -0.139154 -0.491225 +0.209504 -0.179526 -0.495194 +-0.506973 0.228154 0.0749273 +0.342358 -0.505403 0.0427386 +-0.498243 0.223738 0.0192014 +-0.473027 -0.481286 0.144119 +0.135396 0.0812289 -0.497884 +0.0416106 -0.496822 -0.416565 +0.0420347 -0.487911 -0.439198 +-0.411548 0.491586 0.440411 +0.074266 -0.507797 0.000282142 +0.119953 -0.500801 -0.0448449 +-0.443201 0.488363 -0.275487 +0.0949296 -0.493437 -0.0225397 +0.286131 0.493261 -0.420774 +-0.511781 0.120464 -0.411985 +-0.495289 0.196483 -0.415778 +0.467343 -0.492331 0.0617913 +-0.0379493 -0.491521 0.00484974 +-0.0268444 -0.508212 0.0364309 +-0.126072 -0.396428 0.496583 +-0.00614986 -0.506747 0.011626 +0.250789 -0.467357 -0.485794 +-0.499486 0.312593 0.0044148 +-0.425969 -0.251566 -0.489566 +-0.415056 -0.222456 -0.507438 +0.119882 -0.15914 0.499535 +0.144592 -0.136195 0.500634 +0.498371 -0.349492 0.023735 +0.0081996 0.262091 0.50294 +-0.479822 -0.45638 -0.271631 +-0.0201263 0.244007 0.496034 +-0.50802 0.405287 -0.0251932 +-0.513773 0.356179 -0.0643581 +-0.508253 0.384315 -0.0786166 +0.427666 -0.330547 0.496474 +-0.306564 0.260387 -0.511323 +-0.271905 0.31045 -0.500769 +0.502878 -0.0828146 -0.284385 +0.0560059 -0.363808 -0.513176 +-0.489973 -0.449324 -0.0695281 +-0.106538 0.236849 0.498739 +0.066263 -0.390115 -0.503011 +-0.0163374 0.134071 -0.503586 +-0.35271 -0.510264 0.284102 +0.508288 -0.348222 -0.401953 +-0.0684077 0.0384934 -0.5034 +-0.486733 -0.462702 -0.426459 +-0.0958499 0.0553068 -0.499848 +0.464509 -0.482799 0.441179 +-0.0971095 0.0214946 -0.502359 +-0.157688 -0.50315 0.430141 +-0.493246 -0.4471 -0.206543 +-0.496474 -0.0684222 -0.0203305 +-0.416029 0.432972 0.505309 +-0.41835 0.4539 0.492031 +-0.463303 -0.473503 0.0522834 +-0.502864 0.283177 0.114496 +-0.498713 0.326837 0.0854563 +-0.399457 0.503129 -0.334573 +-0.209151 -0.20953 -0.491035 +0.239821 -0.502084 -0.308405 +0.498817 0.029877 -0.425224 +0.418452 -0.509235 -0.06276 +-0.503485 -0.349661 -0.39781 +-0.439799 0.169506 -0.492603 +0.243114 -0.432682 0.488044 +-0.422167 0.199338 -0.491994 +0.440356 -0.496239 -0.0331221 +-0.502496 0.430683 0.300412 +0.0247899 0.508102 -0.202329 +-0.456964 0.120169 0.501587 +0.440615 0.504366 0.122468 +0.459179 0.415383 -0.483951 +0.0107709 0.502301 -0.12152 +-0.507847 -0.264941 -0.306472 +-0.513926 -0.233602 -0.292364 +-0.336022 -0.338776 -0.505988 +-0.45597 -0.277537 -0.485799 +0.493271 -0.444975 -0.30917 +0.494719 0.414345 -0.338802 +-0.455565 -0.253407 -0.4983 +-0.498474 -0.260059 -0.271824 +-0.284907 -0.450802 0.496144 +-0.385786 0.501613 -0.377538 +0.490696 0.4319 -0.125315 +0.497058 -0.0542925 0.264209 +0.498033 -0.00382483 -0.148948 +-0.488698 -0.454694 -0.0173051 +0.501905 -0.0512199 0.287589 +0.50443 0.0590478 -0.0625068 +0.506354 -0.0239942 0.297751 +0.124757 -0.400982 -0.507982 +-0.371606 0.0937099 0.500721 +-0.460032 0.483838 0.391851 +0.0747375 -0.414042 -0.49122 +0.384734 -0.499193 -0.443905 +0.133911 -0.426051 -0.498152 +0.0388537 0.148374 0.490881 +0.495893 0.22902 0.30478 +0.0578692 0.482853 0.439405 +-0.519732 -0.35147 -0.353706 +0.229174 0.511484 -0.418952 +-0.342926 0.146559 0.495784 +0.46261 -0.0252598 0.481731 +-0.502164 0.0486787 -0.0379812 +-0.508096 -0.397092 -0.37351 +-0.152165 -0.500409 -0.393922 +0.284736 -0.473812 0.48877 +-0.21143 -0.508548 -0.420981 +0.324774 -0.505019 -0.438846 +0.492064 -0.107319 -0.271429 +0.466492 0.489231 -0.358181 +0.347781 0.51073 -0.424859 +0.508188 0.320481 -0.189441 +-0.481157 -0.0584577 -0.445191 +0.131241 -0.0877274 -0.49073 +0.441908 0.504321 0.0490239 +0.503553 0.378254 -0.131602 +0.509192 0.344671 -0.18941 +0.107005 0.333068 -0.501693 +0.419394 0.398777 -0.493056 +-0.49667 -0.426772 0.226806 +0.15596 0.471136 -0.470008 +-0.463461 -0.322661 -0.486768 +0.127009 0.354941 -0.510387 +0.37935 0.392363 0.50053 +0.0537727 0.3529 0.51543 +-0.431756 -0.253418 0.494292 +-0.469711 -0.143541 -0.469631 +-0.493116 -0.417153 0.151417 +0.00752529 -0.128138 0.497481 +-0.0193012 -0.151678 0.49501 +-0.514233 -0.400454 0.162862 +-0.470926 -0.292888 -0.479599 +-0.493782 0.449622 -0.408445 +-0.503584 -0.422852 0.172232 +-0.499634 0.314712 -0.341767 +0.127751 0.454014 0.497467 +-0.5098 -0.328088 -0.310155 +-0.516402 -0.357796 -0.299756 +-0.4318 0.332266 -0.505734 +-0.502785 -0.248891 0.061578 +0.46825 0.415165 0.48228 +0.387595 -0.510182 0.391012 +0.467181 0.470249 -0.432475 +-0.114094 0.213797 0.503421 +0.144052 0.503967 0.174428 +-0.186581 -0.293917 -0.496458 +-0.49745 -0.057856 -0.341279 +-0.297135 -0.50213 0.185073 +0.160485 0.345713 -0.505212 +0.215081 -0.157873 -0.495124 +0.269497 -0.151483 -0.506206 +0.150332 -0.487665 -0.462301 +-0.459559 -0.488807 -0.0369718 +0.488297 0.457331 0.171997 +0.51712 -0.376992 -0.321547 +0.280845 0.277571 -0.510184 +0.118438 -0.0596274 -0.506753 +0.503751 -0.316816 -0.341397 +0.513335 -0.37409 -0.35276 +-0.471733 -0.471277 0.337474 +0.499463 0.0404243 0.421096 +0.500041 0.0172072 0.438061 +0.111278 -0.191289 -0.503424 +0.361988 -0.501064 0.30358 +0.0464932 -0.497272 -0.244446 +0.101496 -0.504588 -0.229107 +-0.275535 0.159858 -0.493486 +0.062365 -0.508975 -0.265269 +-0.358564 0.508461 0.276678 +-0.483058 0.0444315 0.473719 +-0.272734 -0.392501 0.505206 +-0.252582 -0.409091 0.49983 +0.503829 0.136625 0.367869 +0.506921 0.206016 0.384139 +0.509839 0.234345 -0.0248081 +-0.497037 -0.0356512 0.278568 +0.510842 0.19156 0.355734 +-0.354288 0.0679891 0.496688 +-0.469457 0.0836966 0.485368 +-0.332376 0.0625656 -0.501256 +-0.345846 0.114871 -0.502144 +-0.41407 -0.498929 0.0403177 +0.0404274 0.0770737 0.490065 +-0.435787 0.110921 0.490429 +-0.512599 0.391866 0.0270841 +-0.39279 -0.51318 0.0509925 +-0.369708 -0.510685 0.0342699 +0.20292 -0.0366745 -0.505489 +0.48731 0.383711 -0.448487 +0.499681 0.221018 -0.0750164 +-0.480174 0.108646 -0.451743 +-0.426882 -0.192237 -0.499178 +0.495406 0.154366 0.270661 +-0.156471 0.244767 0.504779 +0.237177 -0.28673 -0.508425 +0.236704 -0.317709 -0.50515 +0.441023 0.346265 0.494015 +-0.0161179 0.504975 -0.121649 +-0.472338 0.0154456 0.469136 +0.436741 0.486454 0.000797994 +0.50513 -0.409348 -0.0282287 +0.162998 0.139361 -0.503193 +0.38999 -0.476585 0.47007 +-0.0249228 0.490201 -0.145776 +-0.505252 -0.366427 0.312018 +0.475528 -0.119576 0.46615 +0.496777 0.261573 -0.0406662 +0.233712 -0.45371 0.480771 +-0.49689 -0.424077 0.289917 +0.445817 -0.500577 0.0121596 +0.499817 0.336259 -0.429712 +0.440008 -0.499513 0.301959 +0.468819 0.0479562 0.471469 +-0.483798 0.461608 0.279048 +0.224038 0.143473 -0.503824 +0.103114 -0.432652 0.489805 +0.489444 -0.247388 -0.448945 +0.496136 -0.274649 -0.439775 +-0.477892 0.477014 -0.103915 +-0.327193 -0.457332 -0.489885 +0.508041 -0.247668 -0.42808 +0.177692 0.511634 0.290918 +0.0705849 -0.497663 0.342783 +0.116746 -0.497085 0.353347 +0.345718 -0.504618 0.42804 +-0.510674 -0.129842 -0.31829 +0.0731813 -0.0851555 -0.500263 +0.0876425 -0.0584525 -0.4899 +0.0564052 -0.0591896 -0.501591 +-0.448747 0.496631 0.339239 +-0.0161735 -0.494044 0.290762 +-0.383209 -0.500305 0.375045 +0.0168602 -0.505284 0.305139 +0.489771 -0.354986 -0.44993 +-0.292484 -0.426153 0.495975 +-0.274768 -0.415681 0.512028 +0.500381 -0.172715 0.0457893 +-0.0781138 0.276097 0.501443 +-0.0827346 0.307709 0.513787 +0.00388079 -0.506527 0.427974 +-0.306043 -0.0191065 -0.500104 +-0.301721 0.502921 -0.0158487 +0.328562 -0.503656 -0.144733 +0.352059 -0.505911 -0.124174 +0.0609171 -0.120553 0.50733 +-0.491076 0.326142 0.438489 +-0.502493 -0.186906 0.113348 +-0.494817 -0.133964 0.0904866 +-0.368469 -0.506929 -0.0552621 +-0.392715 -0.503858 -0.0660345 +-0.510473 -0.220947 -0.406847 +0.444604 -0.11308 0.494485 +-0.0786867 -0.449144 -0.490184 +-0.510691 -0.201415 -0.418101 +0.484681 -0.465039 -0.0256644 +-0.286478 -0.399543 -0.495888 +0.149854 -0.0623663 -0.503734 +0.0414735 -0.485701 0.447602 +0.188978 0.401881 0.493806 +-0.0979986 0.470879 0.476081 +-0.161033 0.102462 0.508005 +0.130511 0.423368 0.489479 +0.0705049 -0.274375 -0.501782 +0.0940995 -0.303371 -0.503439 +0.460623 -0.483994 0.376453 +-0.34674 -0.508838 0.162355 +-0.370911 -0.50265 0.162109 +0.512066 -0.343406 0.427267 +0.460632 0.285611 0.477221 +-0.496928 0.0988379 -0.0825476 +0.16834 -0.123851 -0.503307 +-0.265852 -0.087927 -0.500699 +-0.458579 -0.179054 0.49222 +-0.252908 -0.133833 -0.494321 +0.4519 -0.00900592 0.500755 +-0.464847 -0.487334 0.275337 +-0.233305 -0.120041 -0.496537 +-0.445289 -0.220554 -0.493812 +0.5059 -0.133794 -0.435581 +-0.212877 -0.111562 0.508384 +-0.248876 -0.0982077 0.494616 +-0.218688 -0.0761575 0.505943 +-0.502599 -0.186775 -0.311709 +-0.506625 -0.213532 -0.309339 +0.411036 -0.508976 0.33501 +-0.321828 0.518299 -0.380803 +-0.369349 0.506567 -0.403589 +0.233007 0.335351 0.50412 +0.489312 -0.353147 0.442913 +0.504113 -0.322664 0.437814 +0.129462 0.47003 -0.484993 +-0.490113 0.195783 0.0593552 +-0.503694 -0.0250949 -0.191294 +-0.492269 -0.0484916 -0.193452 +-0.500079 -0.038186 -0.213548 +0.115716 0.383388 -0.495248 +0.483868 -0.473684 -0.0603957 +0.0121051 -0.470126 -0.486347 +0.512353 -0.292002 -0.13332 +-0.254069 -0.515352 0.325905 +0.357927 -0.0352137 0.500046 +0.347226 0.0144252 0.508129 +-0.135495 0.459797 0.48487 +-0.443386 0.290083 0.485319 +-0.357341 -0.509002 -0.424838 +-0.314153 -0.411823 -0.501808 +-0.0561162 0.473668 -0.485083 +0.491419 0.178242 0.119982 +0.508054 0.174861 0.164389 +-0.237069 -0.33068 -0.510809 +-0.161967 -0.309362 -0.493853 +-0.218686 -0.307621 -0.496343 +-0.419028 -0.367023 -0.504734 +-0.019729 0.346549 -0.502935 +-0.0539204 0.299482 -0.506296 +0.499092 0.363456 0.0283352 +0.503257 0.35946 -0.023578 +0.495634 -0.100306 -0.2403 +-0.467166 -0.235301 -0.481661 +0.49926 -0.14582 -0.241843 +0.513161 0.0927385 0.353852 +-0.0281672 -0.493848 0.167568 +0.487873 0.455605 0.0889971 +0.129483 0.495165 -0.449694 +-0.112138 -0.496122 -0.107844 +0.159367 0.415629 0.509429 +-0.0891763 -0.50253 -0.123299 +0.295938 0.496091 0.129767 +-0.487222 -0.192349 -0.468991 +0.447394 -0.461005 -0.477302 +0.318332 0.253353 0.498485 +-0.379534 -0.402845 -0.498944 +-0.496402 -0.322291 -0.436718 +-0.491687 -0.196491 0.446343 +0.459789 0.477504 0.155809 +0.49524 0.205271 -0.404338 +0.503946 0.17018 -0.435408 +0.510915 0.157181 -0.415566 +0.32833 0.500263 0.206638 +-0.497676 0.436828 -0.0865066 +-0.493382 0.444895 -0.0564886 +0.20012 0.484826 0.44452 +0.0702455 0.200194 0.506686 +0.257401 0.426384 0.494485 +-4.68059e-06 -0.502604 0.11953 +0.00113886 -0.499436 0.152091 +0.0343369 -0.496506 0.133415 +0.321629 0.494681 0.144414 +-0.307959 0.408409 0.50925 +-0.338821 0.423683 0.50953 +-0.158919 -0.498506 -0.0732762 +-0.409215 0.419109 -0.500369 +-0.135407 -0.491084 -0.0907525 +-0.161673 -0.507381 -0.102541 +0.494144 -0.428052 -0.0126361 +0.504413 0.215882 -0.338152 +0.512093 0.221098 -0.306951 +0.288264 -0.23379 0.511812 +-0.482074 0.467776 0.00720359 +0.239442 -0.251431 0.506756 +0.0137075 0.148692 -0.499814 +0.0180355 0.181879 -0.503417 +-0.0563599 0.473527 0.485582 +-0.202371 -0.331116 0.51151 +0.49206 0.150613 -0.123935 +0.453191 0.0141744 0.499728 +-0.219914 -0.380769 0.51425 +-0.0101042 -0.492934 0.466833 +-0.0416187 -0.495459 0.459052 +-0.441911 -0.457363 -0.475208 +0.470967 -0.166516 -0.480662 +-0.00782902 0.500545 0.124901 +0.501338 -0.150301 -0.315225 +-0.470133 -0.174101 -0.476466 +-0.237926 -0.359387 0.511867 +0.287592 -0.0607797 0.492589 +0.234613 -0.0415877 0.49089 +-0.491085 -0.0108998 0.142866 +-0.490089 0.00167063 0.113389 +-0.184587 -0.405314 0.508257 +0.0240438 0.50871 0.141897 +-0.155073 -0.441616 0.494319 +-0.182198 -0.429617 0.495898 +0.494678 0.0746237 -0.303336 +0.489984 0.214504 -0.449019 +-0.507222 -0.137304 0.348695 +-0.505351 -0.192083 0.360753 +0.318723 0.502308 -0.259223 +0.0437875 0.0273914 -0.500128 +-0.168469 -0.462089 -0.474757 +-0.0522577 0.295098 0.512704 +-0.483298 -0.445378 -0.326781 +-0.0226457 0.319394 0.509966 +-0.0214424 0.279363 0.507958 +-0.504669 -0.437866 0.15326 +-0.204772 0.508305 -0.166234 +0.432942 0.501481 0.0951988 +0.0245995 0.503614 0.111915 +-0.361955 -0.109542 0.512633 +0.504392 0.102349 -0.290408 +-0.397067 -0.153896 0.509653 +-0.388491 -0.10444 0.505388 +-0.164488 -0.0319002 0.491945 +-0.171662 0.00250787 0.493142 +-0.179386 -0.211138 -0.49149 +0.480099 -0.07117 0.48025 +-0.393724 -0.484826 -0.448588 +-0.164724 -0.237853 -0.492395 +0.5084 -0.124888 -0.224552 +-0.0673089 0.498964 -0.387336 +-0.186848 -0.218798 0.507979 +-0.208304 -0.246238 0.510286 +-0.0351486 0.235185 -0.504735 +0.00661101 0.307541 -0.498181 +-0.0190707 0.294909 -0.511838 +0.393612 0.496297 0.0491001 +-0.0968119 -0.511367 -0.31819 +0.0814168 -0.498396 -0.201248 +-0.0760982 -0.502276 -0.341073 +-0.107674 -0.502447 -0.347241 +0.20033 0.257757 0.502246 +-0.501482 -0.298206 0.246877 +-0.0955583 0.496609 0.167173 +-0.0610282 0.494706 0.175737 +0.0288302 0.476782 0.452009 +0.498854 -0.132106 0.386494 +0.49894 -0.0754383 0.362503 +-0.49184 0.457474 0.0891255 +-0.501278 0.271254 -0.455436 +-0.21479 -0.450235 -0.479575 +0.313576 -0.393901 0.503851 +0.284072 -0.385916 0.511048 +0.290963 -0.412735 0.505693 +0.253294 -0.199085 0.500249 +0.245337 -0.172742 0.508091 +0.20568 -0.507146 0.398001 +0.416555 -0.322481 -0.50231 +0.49048 -0.0830593 -0.173368 +0.0322565 0.45459 0.494065 +0.494106 -0.0104484 -0.177351 +0.494424 -0.10241 -0.148677 +-0.478874 -0.469717 -0.116025 +-0.158475 0.492799 0.426185 +-0.51169 0.349009 0.429665 +-0.400252 0.209058 0.509127 +-0.229388 0.183338 -0.491387 +0.470443 -0.0431531 0.466401 +-0.430009 0.267194 0.501341 +-0.502102 0.272479 0.037929 +-0.483096 -0.459185 -0.0923909 +-0.0530997 -0.138123 0.50914 +-0.513415 0.299437 0.0343059 +-0.507486 0.283588 0.0608733 +0.497267 -0.0962549 0.232848 +-0.00155398 0.494299 0.161011 +0.00749948 0.0324844 0.505343 +0.501881 0.431546 0.385802 +-0.0424774 -0.0824134 -0.497785 +-0.0379904 -0.0478284 -0.500359 +0.497305 -0.123728 -0.126466 +0.497809 -0.0926001 -0.0888557 +0.442316 0.500717 -0.109872 +0.479853 -0.448439 -0.207497 +-0.509218 -0.0992947 -0.0346011 +-0.495508 -0.0720023 -0.0532709 +-0.512163 0.240081 -0.42351 +-0.505695 -0.409828 0.214417 +-0.385141 -0.506516 0.106581 +-0.0527278 -0.490407 0.120539 +-0.0801759 -0.495729 0.134587 +-0.0545013 -0.505606 0.151045 +-0.501327 0.264179 -0.405223 +0.507715 -0.0723822 -0.42457 +0.504263 -0.0498803 -0.440697 +-0.184898 -0.494894 -0.0844201 +0.501665 -0.102434 -0.428154 +-0.429546 0.507987 0.132159 +0.481102 0.422739 -0.464407 +-0.499085 0.2672 -0.234389 +0.0942931 0.472845 0.471051 +-0.223424 -0.475638 -0.480197 +0.494151 0.429223 -0.000567402 +0.397839 -0.366137 -0.506125 +0.31105 0.0078336 -0.503254 +-0.509594 0.29364 -0.290723 +-0.165728 0.307969 0.506356 +0.43202 0.492974 0.282448 +-0.498805 -0.379954 -0.122546 +0.424061 -0.100064 0.490897 +0.0643114 -0.493388 0.4583 +0.0581151 -0.499783 0.433154 +-0.0976459 -0.078487 -0.498797 +-0.0962564 -0.0459841 -0.501452 +-0.0616146 0.189159 0.503654 +-0.498695 0.19309 -0.0421721 +0.200051 0.509868 0.242311 +0.471137 -0.239641 0.483478 +-0.490975 0.194977 -0.0150665 +-0.498938 0.168165 -0.0270683 +0.509909 0.341229 0.00481851 +0.500613 0.288124 0.00557042 +0.498333 0.286565 0.0343669 +-0.195557 -0.463738 -0.472087 +-0.015745 -0.459486 -0.479058 +-0.229789 0.49023 -0.436696 +0.365962 -0.504362 -0.397578 +0.344845 -0.513054 -0.419855 +-0.496 0.0690125 -0.29035 +0.295275 -0.482465 -0.472063 +-0.498192 0.0746119 -0.322355 +-0.504812 0.104074 -0.299229 +-0.342053 0.502497 0.1862 +-0.507931 0.273689 0.361974 +-0.516425 0.225971 0.351126 +-0.13271 -0.50584 -0.0614043 +0.0174146 -0.382724 -0.496683 +-0.387244 -0.506375 -0.15882 +-0.393315 -0.495698 -0.215012 +-0.414357 -0.495463 -0.152981 +-0.33794 0.508827 -0.0337336 +0.506895 0.41947 -0.0315593 +-0.274115 -0.0113527 -0.509451 +0.259313 -0.329532 -0.499745 +-0.443911 -0.326486 -0.495527 +0.504814 -0.388503 -0.148077 +-0.505412 -0.403224 -0.125293 +0.496174 -0.405609 -0.165283 +0.1654 0.483143 0.447625 +0.41386 -0.506406 -0.392561 +-0.460487 0.221466 -0.495565 +-0.510237 -0.412159 -0.0565214 +0.488115 -0.297848 0.4443 +-0.494671 -0.00865616 0.460571 +0.480885 -0.462954 -0.466515 +-0.43873 -0.277854 -0.492577 +0.495566 0.355206 0.425184 +0.0250023 0.0753391 -0.496002 +0.212123 -0.440148 0.487473 +0.313035 0.420523 0.500865 +0.510081 0.136975 -0.254289 +0.49965 0.129965 -0.282848 +0.410963 0.249562 0.512129 +0.364426 0.290226 0.505129 +0.392594 0.301359 0.513269 +0.200778 0.512403 0.301048 +-0.185294 -0.0889066 0.492699 +-0.305624 0.44154 0.505751 +-0.213554 -0.462171 0.484624 +0.258481 -0.338657 0.500668 +0.231866 -0.319821 0.499283 +0.235227 -0.287104 0.497886 +0.438321 0.0352712 -0.50406 +-0.480076 -0.416388 -0.454971 +-0.352037 0.501489 0.125153 +0.409814 0.221987 0.500351 +0.0938709 -0.50111 0.0597201 +0.217206 0.394585 0.512627 +-0.481343 -0.0540415 0.469633 +-0.223764 0.506162 0.152735 +0.0848342 -0.50001 0.0298919 +-0.421839 -0.41971 -0.49595 +-0.484748 0.471741 -0.336101 +-0.279081 0.487141 -0.460359 +0.354279 -0.27316 -0.504365 +0.25488 0.357352 0.512631 +-0.238223 -0.507024 -0.210132 +-0.505341 -0.369775 -0.0960816 +-0.260704 -0.492838 -0.18864 +0.469676 0.490034 -0.32982 +-0.188645 -0.505787 -0.113419 +-0.216582 -0.50964 -0.122705 +0.282092 0.265592 0.501452 +0.173841 -0.50404 0.108381 +0.200143 -0.496086 0.0589085 +0.482056 0.26318 0.450646 +0.159196 -0.501787 0.0796601 +-0.0620518 0.50153 -0.410216 +0.492271 -0.417262 -0.105958 +-0.00959952 0.495257 -0.406787 +0.166111 -0.494118 -0.4482 +0.25375 -0.468095 0.473958 +-0.497392 0.24461 -0.0725684 +0.0918492 -0.196672 0.501876 +-0.497721 0.277139 -0.0821838 +0.427873 0.234649 0.502901 +-0.193186 -0.481319 0.479817 +-0.454821 0.495189 0.222202 +-0.0833518 0.0381289 0.499519 +-0.424374 0.0427979 -0.499702 +0.314117 -0.507862 -0.412976 +0.24562 0.442452 0.48405 +0.212471 0.448217 0.498025 +-0.501983 -0.404462 0.239034 +0.322968 -0.310478 0.509072 +-0.326182 0.00690428 -0.497448 +-0.455119 0.479362 0.173295 +0.336285 -0.259056 0.50297 +-0.382296 -0.169834 -0.506477 +0.0359456 0.0230558 0.493136 +0.476317 -0.356313 -0.46849 +0.0901405 -0.459878 -0.481383 +-0.348538 -0.176998 -0.497842 +-0.506908 -0.362308 -0.238279 +-0.492947 0.131813 -0.0719708 +-0.498401 0.12475 -0.105404 +-0.495474 -0.453016 0.152249 +0.49178 -0.462497 0.328894 +-0.507549 0.156625 -0.0940081 +0.0949616 0.119218 0.503144 +0.514081 0.0453473 0.356241 +0.506566 0.0696801 0.34938 +0.247848 0.506927 0.425903 +-0.466193 -0.451407 -0.469561 +0.495814 -0.153049 0.281665 +-0.493207 0.131094 -0.197451 +-0.512057 -0.381528 -0.173223 +-0.449219 0.483618 -0.173964 +0.384307 -0.495266 -0.16269 +0.357602 -0.502711 -0.153809 +-0.502637 -0.198895 -0.0335044 +-0.502597 -0.156861 -0.0120176 +-0.362921 -0.466339 0.480753 +-0.499454 -0.201055 -0.00910244 +0.055866 0.454064 0.477237 +0.154621 0.505114 -0.440027 +0.123351 -0.489301 0.45621 +0.104134 0.409989 0.494247 +0.451898 0.0821952 -0.483061 +0.437389 0.127836 -0.490187 +-0.489814 0.441527 0.422268 +0.285291 -0.324848 -0.506781 +0.262864 -0.302837 -0.50958 +-0.149727 -0.0459401 -0.498599 +-0.151384 -0.0771444 -0.509127 +-0.123997 -0.0619299 -0.506554 +0.233468 -0.255802 -0.510803 +0.0438142 -0.502849 -0.00575703 +-0.328699 -0.50762 -0.144844 +0.140587 0.451591 -0.498646 +-0.465402 0.059398 0.480457 +0.226285 -0.22683 -0.50276 +0.502716 0.054662 0.328941 +-0.490771 -0.397689 0.438173 +-0.512372 -0.339071 -0.212617 +-0.494664 -0.00559417 -0.446251 +-0.501723 -0.0246711 -0.405934 +-0.0471864 0.508634 0.324371 +-0.360159 -0.508436 0.113271 +-0.497916 -0.0468373 -0.425272 +-0.487849 -0.110567 -0.429574 +0.479574 -0.460896 -0.294024 +-0.479385 -0.0928162 -0.450818 +-0.452358 0.459847 -0.472677 +0.282064 0.497866 -0.448551 +0.0765551 0.396713 0.495962 +-0.482614 -0.352388 0.46256 +0.133064 0.395993 0.499328 +0.232507 0.490096 -0.442282 +-0.433947 -0.105088 0.496902 +-0.157902 -0.452209 -0.491645 +0.176242 -0.31392 0.505606 +0.51421 0.319317 0.180253 +0.500096 0.324022 0.227298 +-0.24247 0.496691 0.323459 +0.383009 -0.0985309 0.514035 +-0.10911 0.493329 -0.26311 +0.269938 -0.484103 -0.477869 +-0.315677 -0.50666 0.0974182 +0.0113102 -0.504175 -0.111276 +0.0736388 -0.504822 -0.11281 +0.491267 0.0535117 -0.465507 +0.0511912 -0.495764 -0.122935 +0.458463 0.437618 0.473175 +0.501977 0.28342 -0.345459 +0.499105 0.248155 -0.325053 +-0.315754 0.192684 0.508332 +-0.313907 -0.172318 -0.50685 +-0.428338 0.506326 -0.135299 +-0.363788 0.20512 0.502165 +-0.318616 0.235519 0.497271 +0.110931 0.495624 -0.463115 +-0.456737 0.146134 -0.492034 +0.0888696 0.480756 -0.459418 +0.19927 0.0859515 -0.496127 +-0.344353 -0.501541 -0.0987706 +-0.461563 -0.477688 0.021612 +0.436631 0.498512 -0.399874 +-0.345428 -0.508165 -0.0708447 +-0.324577 -0.506014 -0.0593447 +-0.145201 -0.135567 0.493345 +-0.280572 -0.317216 -0.501287 +-0.13815 -0.16965 0.49231 +-0.456003 -0.479752 0.172913 +0.501792 -0.202616 -0.286939 +0.4959 -0.179373 -0.279151 +-0.466932 -0.472265 0.195321 +0.355785 -0.508805 -0.301301 +0.239497 -0.498889 -0.370127 +0.214853 -0.512001 -0.358867 +0.439024 0.122762 0.486844 +-0.0881406 0.512923 0.357182 +0.258836 -0.512485 -0.356954 +-0.504098 -0.313858 0.414537 +-0.492357 -0.070044 -0.410175 +-0.510104 0.223763 0.18662 +0.503307 -0.0707862 -0.230661 +-0.50874 0.10388 0.35179 +-0.392383 0.505806 -0.0615789 +0.443221 0.156579 -0.493753 +-0.410224 0.492348 -0.0860378 +-0.51201 -0.299883 0.357076 +-0.0964818 0.500759 0.409185 +0.508147 0.383693 -0.101058 +0.509168 0.411447 -0.143555 +0.265897 0.506205 0.174622 +-0.491687 -0.469905 0.187753 +0.497847 -0.365478 0.134614 +-0.0178105 0.0121519 0.496729 +-0.0443643 -0.0100209 0.502396 +-0.0615889 0.507856 0.300006 +-0.0499725 0.0249756 0.500616 +0.51277 -0.310661 0.241331 +0.403835 0.14716 0.510207 +0.130202 0.503934 0.120692 +0.272863 0.496411 0.0857352 +-0.41377 0.33241 0.492713 +0.184111 0.513224 0.319684 +-0.451233 -0.0268235 -0.494009 +-0.204802 -0.477277 -0.460904 +0.190988 0.50976 0.349145 +-0.497876 -0.205531 -0.457553 +0.267309 0.511741 0.142607 +-0.486697 -0.131463 -0.452147 +-0.449706 -0.491373 -0.310473 +-0.237962 0.207015 -0.491549 +-0.21268 0.208016 -0.498489 +0.0081655 0.297091 0.495059 +0.480696 0.475494 -0.116674 +-0.229549 0.231555 -0.511555 +0.50004 -0.0957745 0.206652 +0.327633 -0.511983 0.248395 +0.131701 -0.242467 0.503609 +0.511113 0.139878 0.292648 +-0.500406 0.262297 0.0880798 +0.498834 -0.0830065 0.166838 +-0.483606 0.465755 -0.393319 +-0.486151 0.453424 0.156474 +0.398237 0.509721 -0.370391 +0.468945 -0.489117 -0.220574 +0.386339 0.495215 0.073351 +0.406131 0.503173 -0.347547 +-0.331203 0.506609 0.288861 +0.426097 0.149455 0.50588 +-0.324947 0.502428 0.318427 +0.338624 0.329123 -0.504311 +-0.228374 -0.407925 -0.493455 +0.44655 -0.221847 -0.485931 +0.0440957 -0.498081 -0.358299 +0.100788 0.461489 0.490535 +0.0915936 0.496655 0.189528 +-0.149612 -0.482951 -0.475263 +0.503943 -0.0668778 -0.0939557 +-0.497061 0.216155 -0.431759 +0.493943 0.430694 -0.416763 +-0.0712604 -0.0328011 0.492186 +0.113833 0.450359 -0.489273 +-0.44493 -0.495658 0.0089157 +-0.424771 -0.49226 -0.0159303 +0.464938 -0.344357 0.477026 +-0.447024 -0.494226 -0.0190956 +0.16986 0.509617 0.368683 +0.150904 0.51063 0.387897 +0.115768 0.494768 -0.0860927 +-0.053293 -0.506089 0.297405 +0.466232 -0.0458298 -0.473347 +-0.504293 0.423811 -0.00226809 +-0.482626 0.449081 -0.0320001 +0.445813 0.497217 -0.367836 +-0.488927 0.447259 -0.00531057 +-0.0865598 -0.49337 -0.244466 +0.149362 0.502566 -0.0928041 +-0.0586287 -0.506043 -0.247029 +-0.0744777 -0.503937 -0.268902 +0.336592 -0.508836 -0.279972 +-0.434918 -0.222242 0.505634 +-0.205327 -0.504476 0.434626 +-0.206318 -0.502377 -0.0134125 +0.499023 0.336339 0.0370394 +-0.209013 -0.508866 0.016759 +0.222194 -0.4991 0.149117 +0.186459 -0.500588 0.140132 +0.133471 -0.0899635 0.504789 +-0.156453 -0.498133 -0.329595 +-0.211605 -0.512153 -0.288124 +-0.177946 -0.493711 -0.278377 +-0.0102892 -0.497577 0.252105 +0.143762 -0.498742 0.30422 +-0.343422 0.482253 -0.47618 +0.114151 -0.503382 0.30733 +0.133266 -0.501528 0.332714 +0.40742 0.0589828 -0.498439 +0.402438 -0.0112951 -0.497043 +0.406613 0.021679 -0.495096 +-0.297394 0.506399 0.0165041 +0.0390177 0.505802 -0.126198 +-0.177998 0.475258 0.474462 +0.412987 -0.499317 0.226085 +0.160067 0.490445 0.199137 +0.317262 -0.495049 -0.0765094 +0.125945 0.504671 -0.117516 +0.450257 0.483291 0.101556 +0.279549 -0.506539 -0.0731869 +0.296886 -0.503927 -0.046117 +0.2362 0.240416 -0.507469 +-0.109238 0.495251 0.42729 +-0.231825 0.47702 -0.473701 +0.502084 -0.159871 -0.416373 +0.325976 -0.51175 0.130255 +0.0747362 0.502961 0.144642 +0.507911 0.346483 -0.263427 +-0.321527 0.46661 -0.478282 +0.49963 0.384952 -0.222325 +0.503097 0.370864 -0.271931 +-0.429368 0.364795 -0.49899 +0.202232 -0.333043 0.497847 +0.329379 -0.501417 -0.0417915 +-0.179298 -0.0914172 -0.503974 +-0.205078 -0.0733047 -0.497858 +-0.207835 -0.105132 -0.490645 +0.501029 0.324799 0.261188 +0.512074 0.357161 0.275744 +-0.0869799 -0.396622 0.500047 +-0.103808 -0.365623 0.50219 +-0.0687941 -0.368593 0.511696 +0.45816 0.498126 0.409227 +0.502997 0.314838 0.36388 +0.50463 0.348893 0.350746 +-0.489897 0.447408 0.0410086 +0.0967432 0.494086 0.162135 +-0.228204 0.223079 0.497662 +0.10104 0.492293 0.134713 +-0.179719 0.229202 0.498301 +-0.327004 0.495667 -0.0986911 +-0.300893 0.507808 -0.0809735 +0.341737 -0.49821 -0.0121909 +0.38806 -0.499209 0.0146814 +0.359254 -0.499346 -0.0359233 +-0.358126 -0.351104 0.514879 +-0.34271 -0.319774 0.502125 +-0.230207 -0.501943 0.445436 +-0.210622 -0.499803 -0.389339 +0.0579829 0.102845 -0.497463 +0.0876524 0.105767 -0.49134 +-0.0969598 -0.482242 -0.464264 +-0.506106 0.0964875 0.0358305 +-0.494298 0.0883927 0.00424333 +-0.243581 -0.473121 0.485076 +0.0863922 -0.467714 0.481687 +-0.126996 -0.50708 -0.322815 +-0.506992 0.120035 0.0137138 +0.331022 0.509631 -0.134032 +-0.448314 -0.487247 0.040449 +-0.126662 -0.481657 -0.456432 +-0.501172 0.38258 -0.304929 +-0.463793 0.363979 -0.478991 +0.497334 -0.0298159 -0.273798 +-0.497941 0.426879 -0.290911 +0.460509 -0.0788505 0.487039 +0.352539 0.0737962 0.507308 +-0.451582 -0.489819 -0.0671788 +-0.183483 0.0153463 -0.50567 +-0.264919 0.487631 0.470322 +0.471318 -0.465155 0.377998 +0.482085 0.47649 0.00216214 +0.469477 0.270781 -0.480832 +0.13099 0.496117 -0.284783 +-0.308331 0.49833 -0.2454 +-0.217119 0.503043 0.179603 +0.117652 -0.310241 0.511514 +0.101423 -0.250764 0.494918 +0.150028 -0.295156 0.503414 +-0.00257828 -0.492131 -0.0853904 +-0.0437208 -0.503667 0.263823 +-0.0181835 -0.502183 -0.0537975 +0.264167 0.223213 0.50521 +0.501428 0.296998 0.188001 +0.00593641 -0.506933 -0.0357915 +0.124665 0.503691 -0.398717 +0.449385 0.235332 0.502457 +0.156053 0.439948 0.492558 +0.153105 0.461523 0.478281 +0.503921 0.227074 0.113332 +0.505786 0.215556 0.0838453 +0.368799 0.240316 -0.508359 +0.506159 0.195669 0.103897 +0.171674 -0.212903 -0.49006 +0.132358 -0.261304 -0.508543 +0.497937 -0.239076 0.257609 +0.161054 -0.263812 -0.501635 +-0.33537 -0.496384 -0.440711 +0.145477 -0.379647 -0.511087 +0.501408 -0.0809898 -0.384144 +0.500945 0.373129 -0.0454965 +0.510033 0.404399 -0.00100272 +0.496731 -0.0648747 -0.399036 +0.510359 -0.0591788 -0.375154 +-0.402817 0.514492 -0.240761 +-0.339332 -0.0242532 -0.498663 +-0.344366 0.0326268 -0.502854 +-0.208497 -0.443709 0.501819 +0.337318 0.501892 0.0414943 +0.476521 -0.0977533 0.485087 +0.510074 -0.0400449 -0.227089 +0.515213 0.260978 0.306205 +-0.499161 0.434462 -0.32241 +0.123802 0.506149 0.382108 +0.464566 -0.479519 0.127754 +0.496443 -0.184653 0.106225 +-0.496003 0.35709 -0.0935337 +0.49506 -0.156177 0.094433 +0.50588 -0.180614 0.0765429 +0.136746 -0.497122 -0.13782 +0.331475 -0.0016586 0.514131 +0.183888 -0.501292 -0.130338 +0.498578 -0.457054 0.111983 +0.496353 0.112059 0.449307 +-0.236571 -0.449605 0.494569 +-0.227779 -0.332286 0.513327 +0.4943 0.424206 0.344093 +-0.435756 -0.489871 0.378093 +0.194364 -0.501453 -0.378239 +-0.507633 0.0583896 -0.219962 +-0.497408 -0.113548 0.117519 +0.0276602 0.353387 -0.506375 +0.375662 0.511736 -0.380893 +-0.135285 0.505657 -0.378459 +0.499164 0.231115 0.255834 +0.462492 0.489007 0.00167004 +0.50362 0.000905376 0.143989 +0.509518 0.275074 0.277215 +0.504719 0.257153 0.25184 +-0.456851 0.47715 0.0983958 +0.00925052 0.116102 -0.501154 +0.00644436 0.0874251 -0.500202 +0.0306255 0.0974766 -0.489809 +0.423778 -0.493915 0.358104 +-0.443237 0.486909 -0.342534 +0.0120588 0.500998 0.316462 +-0.443658 0.489727 -0.0475558 +-0.267474 -0.495782 0.0422313 +-0.237668 -0.503275 0.0300989 +-0.261929 -0.496146 0.0106536 +0.431605 0.373561 -0.502306 +-0.192183 0.507423 -0.311244 +0.0252458 -0.506705 0.204044 +-0.00151004 -0.501761 0.185192 +0.477847 -0.248739 -0.468263 +-0.087604 -0.498317 -0.0967768 +-0.00535158 -0.499291 0.218039 +-0.455509 -0.15474 -0.485424 +0.504678 -0.368866 0.423363 +0.510001 -0.391076 -0.074884 +0.50143 -0.380766 -0.124517 +-0.515175 0.212048 -0.347899 +-0.183791 -0.495894 0.0338141 +-0.234283 -0.171818 0.491819 +-0.206077 -0.147377 0.500246 +-0.197818 -0.183558 0.502972 +-0.50744 0.194959 0.402129 +-0.495132 0.209483 0.421867 +0.43607 -0.493984 -0.0545366 +-0.448238 -0.184935 -0.483336 +0.391506 -0.501275 -0.40679 +0.509468 0.134467 -0.417458 +0.510221 0.357561 0.0555318 +-0.202033 0.472272 -0.471915 +0.512918 0.322555 0.0906746 +0.508959 -0.352699 -0.430364 +0.506794 0.343508 0.115315 +0.050447 -0.248439 -0.498396 +-0.314712 -0.472315 0.465028 +-0.493686 -0.128062 0.181295 +0.280382 0.503358 0.0321651 +-0.507483 0.367156 -0.136307 +-0.509185 0.400643 -0.168464 +-0.501418 0.38214 -0.111848 +-0.49983 0.347908 0.0663479 +0.48368 -0.454846 0.0560921 +-0.511693 0.345445 -0.00404005 +0.104678 0.0609086 0.502546 +-0.508739 0.177602 -0.39736 +0.461953 -0.472483 -0.446223 +-0.504076 0.223358 -0.370969 +0.425615 -0.0191721 0.490005 +0.0555508 -0.496785 0.190982 +0.431949 0.00902494 0.501713 +-0.458166 0.476065 -0.260398 +0.0895533 -0.505904 0.151404 +0.0704878 -0.495767 0.130031 +-0.509001 -0.0604573 -0.314027 +-0.493709 -0.0793176 -0.292986 +-0.502049 0.0642353 0.0269652 +0.405255 -0.112941 0.511937 +0.433449 0.493274 0.3665 +-0.501976 -0.10798 -0.27886 +-0.0521319 -0.4476 0.495943 +0.104449 0.0797149 -0.500531 +0.120752 0.0527539 -0.49784 +0.487439 0.454843 -0.195048 +0.499275 -0.302043 -0.41009 +0.0532984 0.358259 -0.51017 +0.0308369 0.305118 -0.504964 +0.0757254 0.337614 -0.501808 +-0.496163 -0.119926 0.0165795 +0.499033 0.391911 -0.253778 +-0.499448 -0.121614 -0.362517 +-0.508751 -0.0843064 -0.324879 +-0.503824 -0.140508 -0.340899 +0.502703 -0.07507 0.302303 +-0.121631 0.503683 -0.403367 +-0.453701 0.00838233 0.478818 +0.118701 -0.493172 0.0364652 +0.148956 -0.507821 0.051154 +-0.33926 -0.50453 -0.171953 +-0.310224 -0.498726 -0.168794 +-0.500531 -0.0248243 0.384294 +-0.320266 -0.498568 -0.19494 +0.296664 0.158665 0.499224 +-0.299814 -0.495672 0.0787373 +0.445512 -0.430851 0.48875 +-0.0145515 -0.490812 -0.0188452 +0.464573 0.448349 -0.469168 +0.424136 0.492313 0.0697044 +0.344154 0.172536 0.51554 +0.330865 0.153634 0.503438 +-0.0557954 -0.239473 -0.502579 +-0.501734 -0.426479 0.0600804 +0.0725494 -0.497107 -0.456001 +0.45776 -0.453184 0.46714 +0.152604 0.0537352 -0.493904 +0.246477 0.493372 0.0959254 +0.410687 0.0741818 0.506961 +0.212537 -0.506156 0.110893 +0.508276 0.379077 0.370404 +0.448878 0.475849 0.444749 +0.170076 0.0250852 -0.489839 +-0.098872 -0.503822 0.0162212 +0.490844 -0.462591 -0.415054 +-0.0707648 -0.498475 -0.00507728 +-0.267303 -0.441531 -0.48713 +0.458754 0.482336 -0.386878 +-0.190495 0.487161 -0.459704 +-0.44806 -0.487724 -0.173946 +-0.496521 -0.42396 0.25591 +-0.514965 -0.20725 0.332984 +-0.506445 -0.230896 0.302515 +-0.504755 -0.193541 0.303101 +0.465166 0.468683 0.44435 +0.489333 0.110498 -0.468112 +0.465709 0.106923 0.482404 +0.426761 -0.0280375 -0.501474 +0.173939 0.507753 0.171955 +0.509982 0.0584545 -0.378489 +0.510014 0.0799327 -0.333601 +-0.0794858 0.5084 0.231721 +-0.496543 0.231614 0.420316 +0.00970726 -0.219481 0.497917 +-0.0114614 -0.19169 0.501734 +0.364545 -0.368509 0.502198 +0.48802 0.418724 0.448271 +-0.287583 0.510895 -0.208403 +0.491635 0.430158 0.4288 +0.49206 0.404643 0.428293 +-0.433845 -0.498722 0.0567021 +-0.111579 0.0994934 -0.506045 +-0.0859155 0.49451 0.199095 +-0.271322 -0.504321 0.163079 +-0.0552894 0.494552 0.447423 +-0.287943 -0.494042 0.100939 +0.374605 -0.188691 0.494974 +-0.158009 0.508568 -0.304463 +0.372864 -0.154162 0.502276 +0.401437 -0.170767 0.503098 +-0.429709 -0.487765 0.0870263 +-0.406998 0.506293 -0.116503 +0.464105 0.343018 0.485217 +-0.0551454 0.485571 0.467582 +-0.489732 -0.437665 -0.0954432 +0.498005 -0.444515 0.0688748 +-0.424042 0.50119 -0.157865 +0.506001 -0.118795 0.192527 +0.487151 -0.450652 -0.0781023 +-0.502696 0.0248184 -0.327452 +0.508448 -0.211386 0.393117 +-0.285766 -0.0129388 0.494736 +-0.288794 0.0487309 0.498943 +-0.171006 -0.00606154 -0.506168 +0.412278 0.318319 -0.503815 +0.426419 0.096496 0.505323 +0.440268 0.203711 -0.485042 +0.452116 0.179887 -0.497443 +0.0610567 0.305274 -0.506726 +0.359442 0.459115 0.483233 +-0.468862 0.102193 -0.491892 +0.479361 -0.461226 0.160657 +0.447636 0.485248 0.272202 +-0.114419 0.49367 0.220571 +-0.508626 0.251118 -0.119756 +-0.504176 0.203076 -0.107171 +0.212162 -0.495458 -0.219328 +0.100906 -0.0664588 0.507823 +0.0875348 -0.0887766 0.49827 +0.061335 -0.0933793 0.502621 +0.503483 0.108383 0.376661 +0.504432 0.0739365 0.377117 +0.0498098 0.424698 -0.495473 +-0.310042 -0.315194 0.518393 +0.0317347 0.487115 -0.438563 +-0.505233 0.381819 0.0777082 +0.00923891 0.461168 -0.488922 +0.486839 -0.348804 0.469835 +-0.502288 0.161557 -0.344317 +-0.160871 0.397431 0.512129 +0.486057 -0.219416 -0.435046 +-0.514802 0.103946 -0.368996 +-0.495383 0.156041 -0.375497 +0.494944 0.13353 0.143548 +0.505681 0.0651707 0.143259 +0.498156 -0.108962 0.12181 +0.333103 -0.252054 -0.500226 +0.505777 -0.131652 0.110398 +0.494032 -0.130404 0.141524 +-0.514043 0.3203 0.240438 +0.183901 -0.223408 0.493612 +-0.123044 0.151318 -0.492975 +0.208475 -0.26847 0.495028 +0.154523 -0.263194 0.498712 +0.400523 0.500769 -0.0262918 +-0.441179 -0.349441 -0.510262 +0.452843 0.213295 0.47992 +-0.463694 0.484719 0.363524 +0.509073 0.368418 -0.433242 +-0.504628 -0.249157 -0.408466 +-0.501776 -0.284695 -0.399066 +0.486048 0.453666 0.225168 +-0.5179 -0.315539 0.299473 +0.451813 0.491767 0.181074 +-0.504405 -0.281829 0.337282 +0.494708 -0.26167 0.0262441 +0.488836 -0.42719 -0.226962 +0.510597 -0.235484 0.00578794 +0.510127 -0.13011 0.358484 +0.504727 -0.128963 0.329023 +0.513778 -0.156163 0.34222 +0.504099 0.175093 -0.0314203 +0.454657 -0.489872 -0.36062 +0.318589 -0.446653 0.505608 +0.00941077 0.229073 0.491406 +0.23929 -0.49775 -0.234583 +-0.497654 0.156286 -0.220201 +-0.494385 0.123464 -0.230844 +-0.493818 0.149476 -0.254013 +0.241076 -0.503653 -0.206802 +-0.0849923 -0.33865 0.49537 +-0.200542 0.180401 -0.495698 +-0.207391 0.129019 -0.505796 +-0.258477 -0.156457 -0.494716 +-0.217259 -0.185667 -0.503299 +0.464946 -0.474838 -0.279749 +-0.439685 0.485711 0.407918 +0.15579 0.492662 -0.460376 +0.0633358 0.496896 -0.453819 +0.498884 0.294556 0.303908 +0.503738 0.319806 0.327912 +0.487137 0.00208146 -0.436944 +0.506523 0.32528 0.293294 +0.424696 -0.218865 -0.494196 +0.439715 -0.193109 -0.498318 +-0.510842 0.355262 0.1917 +-0.501884 0.388832 0.209958 +-0.460954 -0.426132 0.487943 +-0.511106 0.379176 0.248683 +0.490912 -0.0315554 -0.097533 +0.498157 0.24109 -0.235339 +-0.285738 -0.504799 -0.00977095 +0.0610617 -0.45857 -0.490475 +-0.312751 -0.509799 -0.0327718 +-0.454309 -0.45091 0.478152 +-0.315924 -0.510393 0.00368663 +0.490949 -0.054587 -0.166635 +0.507143 -0.0904345 -0.117341 +0.50915 0.0983238 0.101909 +0.493592 -0.0279457 -0.131205 +0.500894 -0.205831 0.0556959 +0.492058 -0.232672 0.0371327 +0.501347 -0.236726 0.0663961 +-0.409977 0.365881 0.499213 +0.495898 0.0772775 -0.267592 +0.494572 0.109457 -0.262792 +-0.00369799 0.501092 -0.218945 +0.225752 0.502719 -0.303513 +0.490231 0.467324 0.11385 +0.306404 -0.0442302 -0.501496 +0.0263514 0.493796 0.429825 +0.287937 -0.0714985 -0.495272 +0.467836 0.462586 0.467612 +-0.496783 0.139507 0.452993 +-0.1135 0.496286 0.0972407 +-0.0808104 0.492829 0.108325 +0.217889 -0.501786 0.425437 +-0.110174 0.503035 0.13265 +0.179669 0.515741 -0.336341 +0.162167 0.499409 -0.307436 +0.512811 -0.287664 -0.393202 +-0.497335 0.260429 -0.160151 +0.511313 0.0460799 -0.324285 +-0.50376 0.289891 -0.158615 +0.452851 -0.479291 0.25329 +0.457812 0.455679 0.474094 +-0.30425 -0.505037 -0.294824 +-0.49502 0.272456 -0.136519 +-0.1297 0.435331 -0.493707 +0.0683762 -0.502045 -0.34433 +0.154271 -0.501739 -0.334321 +0.0162218 -0.468031 0.488532 +0.487814 0.290434 -0.454639 +-0.44756 0.499132 0.195667 +0.492031 -0.0799484 0.0531376 +0.501042 -0.0848152 0.0167112 +0.489456 -0.105333 0.0704236 +-0.0783124 -0.256035 0.505122 +0.509869 0.413156 0.170673 +0.50347 0.438306 0.224566 +0.491273 0.043781 -0.220741 +0.466974 0.477032 0.027089 +0.509961 0.0944905 -0.220182 +0.501297 0.0937605 -0.2441 +0.496978 -0.17838 -0.30422 +0.503117 -0.209874 -0.349903 +0.511066 -0.241942 -0.360923 +-0.503639 0.175799 0.116683 +-0.490387 0.168893 0.0843157 +-0.00878357 0.4326 0.503242 +-0.509159 0.201065 0.0946378 +-0.511852 0.35112 0.128651 +-0.0314009 0.4823 0.481663 +0.333573 -0.103668 -0.510352 +0.320918 -0.0738657 -0.501189 +0.396459 -0.0578667 -0.494626 +0.481753 -0.142571 0.454746 +-0.482323 -0.0316309 0.470323 +0.352832 -0.0780399 -0.498997 +0.395493 -0.111312 -0.500704 +0.492409 0.183423 -0.269604 +-0.0920044 -0.0905125 0.500314 +-0.125014 -0.0783761 0.492963 +-0.0982185 -0.0556697 0.497005 +-0.505317 -0.259624 -0.375696 +-0.503832 -0.264931 -0.341771 +-0.508139 -0.162001 0.12601 +-0.497277 -0.111824 0.154355 +-0.508546 -0.159475 0.151442 +0.506394 0.111291 0.148538 +0.194218 0.500994 -0.314339 +0.233948 0.481313 0.44217 +-0.216661 0.0121059 -0.494195 +-0.242028 0.0217947 -0.496524 +0.505062 0.197577 0.300716 +-0.472487 0.464059 0.446173 +-0.245476 -0.00249334 -0.503817 +-0.35495 0.353132 0.502928 +-0.336866 0.329463 0.500125 +-0.387107 0.344305 0.509816 +-0.0393359 0.512371 -0.399115 +0.0141047 0.495101 -0.387795 +0.0329116 -0.453433 0.489829 +0.246176 0.386464 0.514937 +0.212224 0.421377 0.507074 +0.266491 0.406624 0.512166 +0.514307 -0.383461 0.225661 +0.515911 -0.352761 0.219074 +-0.503501 -0.0462598 -0.291707 +0.498679 -0.370148 0.195154 +-0.444749 0.491527 -0.245099 +-0.173304 0.160069 0.499813 +0.451116 -0.166308 -0.493687 +0.0575796 0.501635 0.0155603 +-0.101762 -0.508047 -0.0179087 +0.0429198 -0.476988 -0.457307 +0.515413 -0.2356 0.376113 +-0.13018 -0.506877 -0.0309761 +0.484624 0.463383 0.0283457 +-0.403613 0.0970136 -0.510503 +-0.384569 0.0516015 -0.509804 +0.040714 0.47009 -0.486533 +-0.373558 0.104918 -0.513023 +0.153102 -0.00430777 -0.508287 +0.168716 -0.0345447 -0.491688 +0.187041 -0.00505262 -0.498498 +0.216817 0.499137 -0.267074 +0.479634 -0.475663 0.1025 +-0.375596 -0.219703 0.508543 +-0.377274 -0.261887 0.503465 +0.500552 -0.423593 -0.354819 +-0.407138 -0.238982 0.504496 +0.50123 0.0966347 0.308365 +0.509229 0.1059 0.255539 +0.420622 -0.503543 0.313115 +0.413612 -0.496063 0.258264 +0.390896 -0.510769 0.277772 +-0.465352 0.130376 0.485411 +-0.265933 0.498211 -0.237244 +-0.493937 0.103704 0.178925 +-0.502406 0.0854523 0.202204 +0.502707 0.0447508 0.248345 +0.426452 -0.126864 0.504653 +0.501131 0.0383412 0.302418 +-0.41692 0.115902 0.49573 +0.487082 -0.458002 -0.169761 +0.446079 -0.166749 0.492059 +0.489038 -0.426715 0.119327 +0.460945 -0.0199038 -0.48523 +0.493228 0.0855428 0.281381 +0.44426 -0.502733 0.152634 +0.0756325 0.06889 0.49547 +0.0993359 0.0892987 0.50624 +0.204104 -0.49955 0.447758 +-0.345203 -0.42532 0.497239 +0.480039 -0.448441 -0.473597 +-0.472298 -0.467705 -0.405122 +0.13443 0.504655 0.331339 +-0.00142785 0.39457 -0.506829 +0.301874 -0.100622 -0.510913 +0.0179091 0.418416 -0.507154 +-0.110445 0.191181 0.490683 +0.33998 0.419795 0.503716 +-0.0892164 0.155727 0.49317 +0.450377 -0.0358642 0.501488 +-0.131887 0.176051 0.508568 +-0.031424 -0.080176 0.497185 +0.498422 -0.433234 -0.151515 +-0.0254977 -0.115642 0.49829 +-0.505488 0.0356051 0.318824 +-0.0589329 -0.102929 0.507448 +-0.495955 -0.321484 0.132645 +-0.497698 -0.376689 0.145287 +-0.34501 0.513044 -0.303486 +-0.365863 -0.159425 0.503778 +-0.182044 -0.495027 0.00228011 +-0.452455 -0.488238 -0.363983 +-0.469647 0.0336507 0.490224 +-0.155871 -0.495782 0.0179717 +-0.155731 -0.507868 -0.0136113 +-0.514098 0.337831 0.0316084 +0.45053 -0.257963 0.486246 +-0.499508 -0.343952 -0.176621 +0.50006 0.443146 -0.327654 +0.496005 0.394141 -0.286045 +0.48666 -0.452101 -0.134273 +-0.469686 0.483448 -0.00564199 +0.487307 0.442442 -0.293305 +-0.348053 0.518712 -0.33733 +-0.400006 0.504592 -0.35858 +0.113163 0.497391 0.353614 +0.485763 0.468144 0.270355 +-0.434352 0.413953 0.493389 +-0.456724 0.421663 0.487487 +-0.160829 -0.286437 0.51264 +0.497776 -0.0928462 -0.0428014 +-0.174002 -0.252737 0.503638 +-0.140003 -0.259099 0.498959 +0.363651 0.5013 -0.332903 +0.379911 0.499407 -0.352651 +0.486412 -0.473284 0.00632862 +-0.400487 -0.512561 0.404374 +-0.49652 -0.385311 0.114734 +-0.495269 -0.362578 0.0907891 +-0.507919 -0.337369 0.0679807 +0.358758 -0.131906 0.505102 +-0.423208 -0.332055 0.499365 +0.142664 0.495384 0.360635 +0.315233 -0.139324 0.502311 +0.459174 -0.489036 0.10473 +0.508509 -0.204492 -0.183136 +0.497536 -0.182104 -0.204756 +-0.510115 -0.285949 -0.179801 +-0.195627 -0.279915 0.49655 +-0.495737 -0.257845 -0.17806 +-0.508329 -0.241717 -0.145513 +-0.490156 -0.450377 0.0144878 +0.314482 0.127488 0.512026 +-0.0459331 0.497509 -0.344308 +0.00780109 0.50567 -0.342584 +-0.265507 -0.500302 0.406108 +0.498955 0.150475 0.319917 +-0.222217 -0.501773 0.384133 +-0.249246 -0.511458 0.383588 +0.194 -0.495855 -0.454366 +-0.236483 0.496344 -0.0159473 +0.484832 0.185004 -0.448486 +-0.0428492 0.503823 -0.371608 +-0.26901 0.504761 0.0291192 +0.494291 0.04919 -0.107099 +0.453579 -0.489245 0.397641 +0.499757 0.0912491 -0.0735701 +0.493732 0.073061 -0.118242 +0.301246 -0.508483 0.296837 +-0.107584 0.463029 -0.486868 +0.249963 0.484071 0.470791 +-0.109252 -0.490362 -0.0792936 +-0.105508 -0.505935 -0.0496491 +0.0793522 -0.225447 0.508364 +0.0374875 -0.269436 0.502337 +-0.495506 0.120499 0.429744 +0.470968 0.485676 0.227639 +0.0418343 -0.230554 0.508723 +0.502247 0.34574 0.390083 +0.267842 -0.517562 0.337641 +-0.46347 0.472665 0.0224177 +0.345738 -0.282737 0.500249 +0.375804 -0.282913 0.508665 +0.360235 -0.310605 0.518128 +-0.493748 -0.101866 -0.0668809 +-0.491049 -0.183483 -0.0785849 +-0.494419 -0.105931 -0.0981158 +0.452781 0.283591 -0.491265 +0.462797 0.478538 -0.267847 +-0.107457 0.411209 -0.493101 +-0.088168 0.446045 -0.489768 +-0.501978 -0.0705053 0.190584 +-0.49279 -0.0996162 0.185414 +-0.5033 -0.0806482 0.163588 +0.129683 -0.499466 -0.366656 +0.171719 -0.50107 -0.401302 +0.126792 -0.496548 -0.39708 +-0.435822 -0.191987 0.499917 +-0.495881 -0.273258 -0.451059 +-0.223501 -0.0416961 0.50374 +-0.257964 0.00410542 0.49688 +-0.231962 0.021725 0.50024 +-0.429961 -0.500714 0.119293 +0.490193 -0.130922 -0.15417 +-0.459731 0.0197055 -0.481802 +0.493337 -0.0972551 -0.205826 +0.501245 0.417815 0.407652 +0.49292 -0.130232 -0.197627 +0.275252 -0.493728 0.0783176 +0.219774 -0.492014 0.46175 +0.305049 -0.496966 0.121568 +0.461803 -0.47599 -0.0814908 +0.11835 0.107896 -0.506346 +0.131911 0.13627 -0.503265 +-0.322428 0.496931 0.0368953 +0.404189 -0.429714 0.490115 +0.0166851 -0.493437 -0.455651 +0.121508 0.502909 -0.346404 +0.502654 -0.0500084 0.409947 +-0.486743 -0.32252 -0.452268 +0.499374 0.00994118 0.410145 +-0.0941307 0.511503 -0.34596 +-0.397574 -0.512278 -0.358346 +-0.494852 0.444806 -0.378503 +-0.274314 -0.465514 -0.481523 +0.114982 0.508885 -0.205736 +-0.251055 -0.482865 -0.478484 +0.0899538 0.0522514 -0.50215 +-0.502868 -0.1544 0.176463 +-0.0310074 -0.500677 0.198997 +-0.495336 -0.118004 0.208671 +-0.509159 -0.137256 0.230841 +-0.302689 0.295923 -0.497974 +-0.385988 0.291927 -0.517628 +-0.052296 -0.399518 0.512328 +-0.37074 0.238824 -0.505066 +0.194431 -0.448507 -0.484459 +0.188475 -0.432562 -0.49788 +-0.465898 0.48323 -0.322903 +0.172979 -0.443778 -0.487678 +-0.499282 0.298316 0.188651 +0.50421 0.397611 -0.43357 +-0.502389 -0.343429 0.404654 +-0.135159 0.492848 -0.238134 +-0.0530651 0.502517 -0.312205 +-0.502397 0.274182 0.418732 +-0.489991 0.273888 0.44038 +-0.494318 0.250303 0.429701 +0.00641033 -0.283419 -0.508832 +0.0421212 -0.337028 -0.50853 +-0.0652453 -0.477701 0.466022 +0.0572083 -0.30718 -0.497124 +0.477307 0.269222 0.472258 +0.494595 -0.277421 -0.060959 +-0.284945 -0.0460879 0.507162 +-0.283324 -0.0820176 0.513007 +-0.320591 -0.0633731 0.495685 +0.0350876 0.507769 -0.363251 +-0.506626 0.149865 0.37782 +-0.504133 0.181527 0.426241 +0.257623 0.49412 -0.0129247 +0.208432 0.507512 -0.0126122 +0.32432 -0.508038 0.177339 +0.195554 -0.492685 0.176774 +0.196457 -0.507733 0.228602 +0.213676 -0.503785 0.205404 +-0.0486031 -0.244716 0.501524 +-0.0180673 -0.229662 0.511066 +-0.0207822 -0.265236 0.495216 +0.473112 0.46156 0.240239 +-0.494378 0.223121 -0.131145 +-0.496628 0.173939 -0.158961 +-0.50525 0.232873 -0.158692 +0.476107 -0.370591 0.480057 +-0.323537 0.0938811 -0.503572 +-0.158655 -0.4846 -0.447507 +-0.469366 -0.464715 0.421364 +-0.155111 -0.502007 -0.423466 +0.435968 0.467617 -0.469661 +0.50881 0.184045 0.271305 +-0.488204 -0.0833704 0.448116 +-0.505075 -0.043537 0.42056 +-0.509538 -0.192742 0.0522598 +-0.506438 -0.218257 0.0716077 +-0.0172538 0.102294 -0.505388 +0.474079 -0.479272 0.178373 +-0.505877 -0.198858 0.0206287 +-0.314931 0.281613 0.513741 +-0.138764 -0.494611 -0.173763 +-0.324375 0.306046 0.506197 +-0.36743 0.436404 0.499656 +0.497503 0.156903 -0.152197 +0.495283 0.207235 -0.135571 +0.458234 0.477375 -0.23959 +-0.471414 0.254791 0.481129 +0.491915 0.189281 -0.164287 +0.508471 -0.300817 -0.432991 +0.138674 0.490598 -0.0613472 +0.265614 0.495857 0.210191 +0.189345 -0.491253 -0.245312 +0.178329 -0.492114 -0.215275 +-0.138035 -0.00876061 0.496059 +-0.260831 0.473868 -0.473257 +-0.111091 0.0147091 0.506517 +-0.104596 -0.0206955 0.507332 +-0.333642 -0.376163 0.516715 +-0.497781 -0.352323 0.26129 +-0.515644 -0.373976 0.280673 +-0.505937 -0.379265 0.250538 +-0.262737 -0.492893 -0.443225 +-0.211311 -0.504004 -0.0938338 +0.0671088 -0.147031 0.50491 +0.100184 -0.109505 0.490939 +0.111538 -0.132638 0.502889 +-0.483933 -0.270032 -0.46911 +0.143104 0.5073 -0.221867 +0.16293 0.499478 -0.272484 +0.385863 0.501678 0.180193 +-0.485187 0.204887 -0.472915 +-0.00832723 0.471419 -0.48288 +0.489328 -0.464438 -0.387621 +0.0952086 0.500437 -0.359353 +0.310439 -0.493236 0.426281 +-0.0744919 -0.22581 0.490709 +-0.100983 -0.211993 0.498997 +-0.0761291 -0.193493 0.501975 +-0.494434 -0.254626 -0.0205991 +0.43132 0.493701 -0.26132 +0.00890044 0.507505 -0.312525 +-0.334608 -0.494183 0.434705 +-0.296851 -0.500715 0.409718 +-0.325906 -0.509443 0.417865 +-0.468829 -0.275927 0.482594 +-0.484493 -0.469972 0.210111 +-0.119076 0.0754421 -0.501989 +-0.352635 0.495715 0.445903 +-0.338803 0.486194 0.466915 +-0.135206 0.10004 -0.502133 +-0.251698 0.500454 -0.203413 +-0.149513 0.071648 -0.489433 +-0.489983 -0.0808623 0.106052 +-0.493775 -0.420316 0.374605 +-0.505302 -0.0434077 0.0673205 +-0.491647 -0.0299056 0.118863 +0.120651 -0.00356344 -0.504944 +0.103895 -0.031268 -0.49649 +0.265115 -0.508694 -0.431631 +0.283604 -0.497106 -0.407793 +0.294861 -0.50312 -0.434484 +-0.255529 -0.506953 0.26327 +-0.23015 -0.506898 0.239678 +-0.262329 -0.501434 0.230154 +0.498473 -0.450479 0.14119 +0.498053 -0.446308 0.170686 +-0.449341 0.196981 -0.492754 +-0.0947223 0.486433 -0.45126 +-0.299879 -0.374609 0.506645 +-0.265859 -0.481522 0.468361 +-0.322288 -0.346453 0.512403 +-0.267461 -0.365013 0.499189 +-0.435852 0.385247 0.501074 +0.514293 0.372007 -0.0736594 +-0.500661 -0.158515 -0.443235 +-0.49658 -0.180458 -0.427727 +0.443615 0.484042 -0.454591 +-0.136337 -0.493519 0.442369 +-0.101454 -0.500713 0.440791 +-0.477105 0.461731 0.0332551 +-0.302495 0.45087 -0.483252 +0.482729 -0.139093 -0.451338 +-0.203213 0.493802 0.205431 +-0.475181 -0.453438 0.446701 +0.15738 0.00894269 0.494932 +0.512888 -0.106484 0.404305 +0.494105 -0.110306 0.427534 +0.491671 -0.081022 0.417878 +-0.0530274 -0.495903 -0.061012 +-0.0623266 -0.493635 -0.0894508 +-0.0823521 -0.492435 -0.0691827 +0.516468 0.276481 -0.305014 +-0.232859 -0.507437 -0.000988614 +0.512516 0.268995 -0.272209 +0.401756 -0.394648 -0.50283 +-0.33048 -0.290307 0.512904 +-0.502374 -0.265804 0.431602 +-0.51405 -0.274362 0.362047 +-0.206626 -0.490156 -0.0668973 +0.495117 0.39561 -0.0541977 +-0.45107 -0.237645 0.486488 +0.0222643 0.246271 -0.503894 +-0.256695 0.493808 0.223724 +0.0855687 0.238891 -0.492585 +0.0799053 0.273793 -0.503306 +-0.38387 -0.515074 -0.263856 +-0.477366 0.409297 -0.469161 +-0.140327 -0.418194 -0.494946 +-0.276702 0.420777 0.499244 +-0.410257 -0.499085 -0.275485 +-0.407383 -0.500983 -0.238638 +0.31636 0.503921 -0.408704 +-0.265315 0.0168281 -0.500672 +-0.222675 0.502884 0.234935 +0.288462 0.476073 -0.476467 +0.317622 0.499652 -0.441679 +0.434332 0.208967 0.498131 +0.509767 0.265244 0.222473 +0.505726 0.253303 0.168066 +0.506879 0.219964 0.177248 +0.126784 0.187374 -0.489713 +0.457352 -0.344269 -0.500748 +0.286916 -0.510743 -0.23855 +0.312276 -0.511803 -0.194201 +-0.150724 0.191575 -0.504239 +-0.148252 0.16286 -0.493246 +-0.126672 0.179877 -0.500796 +-0.237125 -0.482991 0.460922 +0.348444 -0.304043 -0.499599 +0.343913 -0.336905 -0.511651 +0.372471 -0.321965 -0.508257 +0.341632 0.501805 0.131543 +0.358312 0.500313 0.185519 +0.296326 0.401134 0.507188 +-0.451734 0.0499319 0.491272 +-0.49646 0.0603437 -0.454638 +-0.367286 -0.410215 0.504329 +-0.507192 0.0888903 0.118222 +-0.489668 0.0635395 0.107452 +0.389311 0.513356 -0.325024 +-0.492451 0.0595827 0.138377 +-0.497421 0.0729101 0.173099 +0.232312 -0.219064 0.495824 +-0.50145 0.0393786 0.169936 +-0.0319334 0.509245 0.063766 +-0.16001 -0.499348 0.450513 +-0.106433 -0.180715 0.495413 +0.226325 -0.503429 -0.277658 +-0.448388 0.495373 -0.129997 +0.239857 -0.493275 -0.258383 +0.253872 -0.501186 -0.277238 +0.105386 -0.159515 -0.503188 +0.13797 -0.166506 -0.506985 +-0.496995 0.055697 0.375544 +0.147841 -0.139224 -0.500255 +-0.251384 -0.50379 0.10127 +-0.217228 -0.497222 0.118221 +0.468945 -0.455326 0.457574 +-0.21653 -0.490397 0.0829824 +-0.437216 0.491292 -0.078863 +-0.0588093 -0.504815 0.211181 +-0.0658234 -0.499769 0.240123 +-0.0358791 -0.505442 0.230483 +0.496511 0.456371 0.430346 +0.223137 -0.480887 -0.48021 +-0.108199 -0.492642 0.149318 +-0.135611 -0.50436 0.162573 +-0.111729 -0.49613 0.183465 +0.116328 0.492379 0.23716 +0.117129 0.505307 -0.00745814 +-0.477029 0.407527 0.458879 +-0.41805 0.182454 0.496054 +-0.115928 -0.492822 -0.164909 +-0.139519 -0.495878 -0.149194 +0.217326 0.484018 0.469169 +-0.113528 -0.492279 -0.136537 +-0.480095 0.457192 0.230144 +0.497025 0.238245 -0.393237 +0.505859 0.266172 -0.413921 +-0.39358 0.471328 -0.486745 +0.145385 0.494261 0.24926 +-0.00247658 0.509767 0.0731087 +0.125136 -0.340715 0.505427 +0.120337 -0.286901 -0.493433 +0.0668538 0.497099 -0.313641 +0.496631 0.346594 0.145514 +0.16123 -0.50214 -0.150067 +-0.106676 -0.452898 -0.49019 +0.499075 0.244859 0.278822 +0.21742 -0.503196 -0.168282 +0.163887 -0.506839 -0.183787 +0.42084 0.488799 -0.468192 +0.0977298 0.495593 -0.297966 +-0.0919491 0.501675 -0.194672 +0.507756 0.142501 -0.0421664 +0.319576 -0.418784 0.494865 +-0.0999795 0.506163 -0.227779 +-0.258698 -0.495968 0.450234 +0.494274 -0.437364 0.0458255 +0.0561235 0.507173 -0.214881 +-0.134606 -0.501892 0.285081 +-0.278446 -0.499262 0.431286 +0.497774 -0.239985 0.402431 +0.451764 0.49433 0.0258338 +-0.505998 0.316259 -0.437348 +0.512291 -0.295695 0.427852 +0.507361 -0.242882 0.43039 +-0.495906 -0.351352 -0.118411 +-0.496222 -0.35891 -0.0668879 +0.0135765 0.00123236 0.499463 +0.0450397 -0.00670156 0.506908 +0.0224819 -0.0318545 0.493704 +-0.476791 -0.469936 0.1129 +-0.505358 -0.334571 -0.279444 +-0.499498 0.382187 0.171635 +-0.0583972 0.329501 0.507255 +-0.504565 -0.310988 -0.22604 +0.467144 -0.124105 0.491076 +-0.49887 -0.334732 -0.237762 +0.46017 0.489429 0.129103 +-0.503037 0.260753 -0.019465 +-0.491047 0.236878 -0.0184283 +-0.503587 0.241654 -0.0407792 +-0.319522 -0.507706 0.0359991 +0.485959 0.260557 -0.465768 +-0.324062 -0.505403 0.0684861 +-0.29568 -0.507377 0.0535933 +0.440883 0.493102 -0.0481467 +0.488485 -0.163286 -0.439287 +0.0956968 0.496713 -0.330188 +-0.105528 -0.498944 0.380812 +0.486338 0.370605 -0.471069 +-0.126981 -0.502621 0.413393 +-0.16919 -0.502118 0.380083 +-0.182401 -0.49833 0.419227 +-0.494715 0.0472692 0.42891 +-0.139774 -0.499821 0.381447 +0.188396 0.289138 0.496614 +0.167925 0.262203 0.500821 +-0.489214 -0.184334 -0.446642 +0.506229 -0.0201012 0.398 +0.501241 0.013102 0.360427 +0.505226 -0.0478882 0.38018 +0.443217 0.156186 0.483977 +0.123046 -0.421083 0.503828 +-0.324272 -0.511959 0.271323 +0.456546 0.253526 -0.494162 +-0.322023 -0.498463 0.23889 +-0.0775018 -0.501499 0.103431 +0.105636 0.506212 -0.0551889 +-0.373052 -0.511645 -0.206171 +-0.494358 0.102573 0.404709 +0.49704 0.45446 -0.146637 +-0.232261 -0.498565 -0.0734952 +0.507305 -0.193262 0.236822 +0.500592 -0.175402 0.259975 +-0.452567 0.491011 0.454745 +-0.436705 -0.134187 0.494929 +0.180638 0.112662 -0.505729 +0.287198 0.0697886 0.495608 +0.149365 0.110101 -0.500897 +0.167132 0.0831409 -0.49073 +0.341481 -0.0453546 -0.511761 +-0.0848043 -0.445985 0.485397 +-0.506549 0.317061 0.273925 +0.489384 -0.44201 -0.370969 +-0.511732 0.342822 0.292334 +-0.512947 0.313455 0.306252 +0.495686 0.186616 0.0767653 +0.489998 0.159616 0.0740793 +-0.472289 0.486672 0.278792 +-0.393078 0.49124 0.473351 +0.046942 0.0767734 -0.496363 +0.0330651 0.0542308 -0.500013 +-0.49272 0.0344136 0.399388 +0.060482 0.0524367 -0.509592 +-0.489355 -0.225798 -0.444682 +0.503604 -0.190256 0.434419 +0.49682 -0.159712 0.397203 +0.502008 -0.218223 0.445044 +0.506806 -0.320597 0.167818 +-0.225288 0.104945 -0.507603 +0.514774 -0.332082 0.139511 +0.503901 -0.353488 0.165905 +-0.480225 -0.459725 -0.162473 +-0.402447 0.493895 -0.453922 +0.495508 0.460364 -0.121645 +0.498533 0.401296 -0.0835429 +0.369308 0.501891 -0.226765 +-0.435641 0.502295 -0.17614 +0.461496 0.471277 0.459484 +0.114965 0.161428 -0.506902 +0.100488 0.185574 -0.504574 +0.0315548 -0.496549 0.414103 +-0.442856 -0.485352 -0.392193 +0.498778 0.178966 -0.347197 +0.502634 0.144355 -0.363959 +-0.509329 -0.290423 0.400276 +-0.459378 -0.493028 -0.151359 +-0.228214 -0.504227 -0.0295546 +-0.495997 -0.448445 -0.177834 +-0.246761 -0.508137 -0.0492208 +-0.25543 -0.504193 -0.0202608 +0.494015 0.411981 0.29238 +0.505747 0.379778 0.336123 +0.301991 -0.259723 -0.509321 +0.293619 -0.292613 -0.497285 +0.324737 -0.282661 -0.509525 +-0.069219 -0.423808 0.497288 +0.118294 -0.497195 -0.332615 +-0.50482 0.289197 0.255924 +-0.492888 0.227278 0.21993 +-0.493353 0.261155 0.197742 +0.209625 -0.0472181 0.498162 +0.499086 0.044168 -0.189113 +0.169455 -0.0601851 0.495606 +0.342167 -0.467588 -0.475573 +0.381813 0.131326 0.501121 +0.16356 -0.0382311 0.500301 +-0.486825 0.457821 -0.244536 +-0.03737 -0.42344 0.489464 +-0.512725 -0.394456 -0.146483 +0.478313 0.468807 0.0931504 +-0.393164 0.311235 0.511745 +0.415764 0.494351 0.0474003 +-0.341273 0.285853 0.507322 +-0.396797 0.273264 0.514098 +0.259129 0.24597 0.503313 +-0.361111 0.499886 0.367668 +-0.416339 0.506106 0.401436 +-0.385186 0.499232 0.341873 +-0.358262 0.00313083 -0.511989 +-0.392294 0.00142814 -0.507838 +-0.38549 -0.0570257 -0.510297 +-0.354287 -0.515077 -0.254632 +-0.323754 -0.497698 -0.244206 +0.228966 0.506922 -0.363262 +0.211925 0.513304 -0.389555 +0.263701 0.327082 0.510241 +0.294191 0.318746 0.517245 +-0.206953 0.46848 0.469928 +0.0198665 -0.482243 0.452399 +0.379847 -0.0192163 0.513684 +-0.484951 -0.440447 -0.151271 +-0.476984 0.178526 -0.474472 +-0.476203 0.469358 0.253206 +-0.49271 0.439231 0.233581 +-0.109082 -0.506395 0.29386 +-0.08069 -0.507584 0.272822 +0.198099 -0.364905 0.51232 +0.256089 -0.40499 0.497121 +0.192411 -0.396238 0.509116 +0.512841 -0.363183 0.280436 +0.510154 -0.362587 0.313879 +0.508942 -0.301169 0.271972 +0.0772938 -0.428673 0.50711 +0.431227 0.299549 -0.491423 +0.23511 0.464798 -0.484059 +-0.0741817 -0.489599 -0.444734 +0.404042 -0.0318846 0.496321 +0.40278 0.000605222 0.500766 +-0.507862 -0.379992 -0.400054 +0.0844805 0.160779 -0.489554 +-0.468676 0.226106 -0.47479 +0.499897 -0.218652 -0.411477 +0.0487447 0.162381 -0.507147 +0.0696901 0.132052 -0.492269 +-0.277776 -0.310289 0.515204 +-0.134457 0.504318 0.113556 +0.429606 0.504187 -0.024671 +0.507863 0.260411 0.0201879 +0.490538 -0.459509 0.252366 +-0.220625 0.390508 0.51124 +0.380993 -0.46913 0.49073 +-0.249135 0.40635 0.50976 +-0.193172 0.40634 0.498559 +-0.0859395 -0.125244 0.4931 +0.476778 -0.278636 0.466783 +-0.0804024 -0.159667 0.508402 +-0.112464 -0.147181 0.508373 +0.370963 0.205154 0.515852 +0.392734 0.208808 0.498157 +0.389843 0.186573 0.510527 +0.507351 -0.261242 0.181163 +0.493206 0.0307503 -0.452048 +0.47511 -0.397119 0.472926 +0.502892 -0.211144 0.142628 +-0.413855 -0.508457 0.377759 +-0.498348 -0.453166 -0.399272 +0.494773 0.0987876 -0.316638 +0.475966 -0.268376 0.488487 +0.500262 0.150335 -0.302468 +-0.221294 0.467769 -0.48574 +0.513644 0.14658 -0.330823 +-0.118884 0.352676 0.503376 +0.501497 -0.300348 -0.456506 +-0.072114 0.388392 0.511479 +-0.0466216 0.379151 0.507389 +0.505442 -0.189915 -0.429052 +0.471082 0.061653 -0.47815 +-0.0662154 0.360508 0.502631 +0.216777 0.508681 0.384762 +-0.0808939 0.462011 0.483488 +0.49772 -0.301498 -0.0494067 +0.50504 -0.363291 -0.0290991 +0.14122 0.499205 -0.360224 +0.434545 -0.495494 0.41009 +0.178761 0.508292 -0.386745 +-0.421123 0.496592 0.0446529 +0.442032 -0.48723 0.435849 +0.236144 -0.0996562 -0.502514 +-0.462232 -0.371288 -0.483724 +0.126771 -0.0697835 0.500218 +-0.496419 -0.0756895 -0.085926 +0.26084 0.450754 -0.500961 +-0.173784 0.497838 0.290266 +0.507833 0.0173317 -0.304893 +0.505023 0.0151851 -0.280774 +0.512768 0.043096 -0.284634 +-0.433356 0.500478 0.000621944 +-0.438273 0.499978 0.0269036 +0.512731 -0.398987 -0.103097 +-0.505002 -0.131505 0.440065 +-0.266695 -0.280036 0.500836 +-0.450546 -0.490657 0.44965 +-0.431475 0.496657 0.0684032 +0.263346 0.459491 0.478756 +-0.420552 0.505285 0.0902231 +0.479511 0.316709 0.484229 +-0.443761 0.481247 0.431782 +-0.120655 0.472331 0.473965 +-0.000528688 -0.49631 -0.138151 +-0.0472578 -0.505025 -0.112528 +-0.0518129 0.404745 0.507125 +-0.0178907 -0.499884 -0.112637 +-0.229141 0.497174 -0.229617 +-0.216534 0.507477 -0.196898 +0.506834 0.0646655 0.433676 +0.497662 0.0787327 0.450636 +0.4968 -0.3403 -0.094073 +0.292585 -0.448811 0.491743 +-0.472431 -0.394435 -0.480227 +0.499684 -0.295453 -0.0775694 +0.512803 -0.319859 -0.119734 +-0.0557071 0.505412 0.0854151 +0.141233 -0.115361 -0.49465 +0.113948 -0.111123 -0.492395 +-0.250148 0.506502 -0.296899 +-0.215489 0.512752 -0.287136 +0.496478 -0.187778 -0.398876 +-0.299492 -0.28479 0.499867 +0.504529 -0.187072 0.408618 +-0.240746 0.496393 -0.263348 +0.379446 0.49868 -0.271578 +0.364204 0.514363 -0.301442 +0.398889 0.514954 -0.295493 +-0.181169 0.503346 -0.279373 +-0.145646 0.492969 -0.272351 +-0.281819 0.50772 0.263554 +-0.285469 0.5053 0.288973 +-0.307595 0.498272 0.275206 +0.0226332 0.514165 0.348873 +0.127358 0.509462 0.299974 +-0.131331 -0.0436872 0.506927 +0.314881 -0.507484 -0.224671 +0.363665 -0.501913 -0.183343 +0.347219 -0.498863 -0.243019 +0.476769 0.0189672 0.469313 +0.498313 -0.268942 -0.00394525 +0.11279 0.204674 -0.508193 +-0.480385 -0.468861 -0.292181 +-0.0259378 0.502716 0.185388 +0.346913 -0.191562 -0.502598 +0.416089 -0.192558 -0.506464 +0.377545 -0.142955 -0.504938 +0.135763 -0.0325904 -0.493093 +-0.484392 0.169816 0.443969 +-0.252281 -0.0324758 -0.505894 +-0.330588 0.508657 0.00450019 +-0.229229 -0.0534331 -0.509546 +-0.133048 -0.457057 -0.49672 +-0.0635098 0.50542 0.0536984 +-0.0961284 0.499066 0.042041 +-0.0720625 0.508678 -0.00366331 +0.485605 -0.47264 -0.0930427 +-0.284378 0.503523 -0.308489 +-0.502317 0.442464 0.180829 +-0.312622 0.505661 -0.286824 +-0.317019 0.505127 -0.32214 +-0.0587177 0.102615 0.500511 +0.51205 -0.370633 -0.0970319 +-0.0236417 0.0814536 0.497232 +-0.481445 0.464232 -0.159082 +-0.0545433 0.0613328 0.501962 +0.430968 -0.278725 0.494842 +-0.182206 -0.123169 -0.491598 +0.494099 -0.273589 -0.465113 +0.441384 -0.310857 0.494894 +0.431931 -0.244969 0.498773 +0.434885 -0.489988 0.209507 +0.354314 0.500992 -0.131495 +0.435122 -0.486089 0.179765 +0.414805 -0.507964 0.193645 +0.428591 0.502965 0.333473 +-0.175776 -0.491238 0.463274 +-0.220829 0.442259 0.494787 +-0.219384 0.511932 0.312081 +-0.23674 0.511209 0.29636 +-0.262369 -0.184923 -0.494412 +-0.106103 0.494632 0.448138 +-0.177219 -0.349371 0.510651 +-0.322035 -0.198576 0.515038 +-0.291377 -0.213357 0.500579 +-0.319372 -0.23046 0.500895 +-0.0725563 0.509937 -0.251109 +-0.482005 0.453847 0.412518 +-0.0337397 0.500767 -0.239395 +-0.492079 0.454947 -0.110253 +0.00414267 -0.125957 -0.500095 +0.0340385 -0.118168 -0.504942 +0.496087 -0.432703 -0.0667394 +0.0507356 -0.496728 -0.0642826 +-0.29606 0.50193 -0.370911 +-0.0374684 -0.48129 0.478716 +0.389253 0.513323 -0.0541468 +0.0720496 -0.0306182 -0.497857 +-0.508742 0.141498 -0.430685 +-0.49821 0.435197 -0.442875 +0.383133 0.509543 0.00237361 +-0.477114 0.470392 0.305864 +0.238287 -0.497796 0.316505 +0.454803 -0.255999 -0.477985 +0.270586 -0.505219 0.260341 +-0.142254 0.507263 -0.427815 +0.369739 -0.478759 -0.479493 +-0.0891936 0.498535 -0.406012 +0.50043 -0.295866 -0.191112 +0.477895 -0.020776 -0.471617 +-0.259544 -0.0630165 -0.494252 +0.107855 -0.0161621 0.498782 +-0.472167 0.127944 0.466772 +0.121458 0.509839 0.268157 +0.479626 -0.0656583 -0.465306 +-0.502273 0.134461 0.350949 +0.0676774 0.495035 0.277344 +0.48035 0.139198 -0.464642 +-0.478316 0.470008 0.107878 +-0.311025 0.506529 0.149591 +-0.340844 0.498722 0.15483 +-0.496869 0.23525 -0.396223 +-0.323186 0.502422 0.129625 +-0.283074 0.496488 0.446568 +-0.277697 0.500939 0.106917 +-0.0355965 0.500124 0.151039 +-0.0457947 0.498462 0.11754 +-0.0455876 0.499828 -0.275425 +-0.314247 0.512936 0.205014 +-0.505817 -0.233364 -0.354286 +-0.283629 0.498178 0.213801 +0.436388 -0.502114 -0.377176 +-0.35039 0.514858 -0.0878746 +-0.409283 0.499846 -0.00775609 +-0.51069 -0.207865 -0.334701 +-0.208397 0.502937 0.290985 +0.459823 0.136877 0.477842 +0.251065 0.274466 0.503569 +-0.48583 0.461601 -0.0797285 +0.499925 -0.432829 0.0168095 +0.313272 -0.346076 0.499421 +0.499259 -0.323897 0.461505 +-0.419815 0.483627 -0.426746 +-0.266379 0.494376 0.421777 +-0.27216 0.508686 -0.176072 +0.215839 0.497597 0.424558 +0.14879 0.496526 0.427586 +0.226851 0.50798 0.05589 +0.191681 0.506354 0.118598 +0.168961 0.489753 0.059047 +0.500901 -0.21386 0.0897638 +-0.170862 0.496487 -0.334819 +0.450036 -0.483871 -0.0447375 +-0.151613 0.514112 -0.356431 +-0.505561 -0.0144658 -0.295574 +-0.50108 -0.00106607 -0.240848 +-0.379731 0.50395 -0.0941374 +0.120245 -0.459912 -0.471824 +-0.509271 -0.0274131 -0.261915 +-0.0134106 0.498136 0.223047 +0.357574 0.507675 0.387412 +-0.0461921 0.493697 0.245682 +-0.136751 0.495898 0.326879 +-0.165723 0.50349 0.321585 +-0.0147786 0.501173 0.261231 +-0.463707 -0.483553 -0.450454 +0.266396 0.325251 -0.515812 +0.155469 0.464488 -0.490024 +0.501758 -0.321416 0.412925 +-0.502563 0.119551 0.128324 +-0.49567 0.150885 0.139088 +-0.494349 0.125833 0.159159 +-0.0828414 0.500525 -0.0792144 +-0.473305 0.472337 0.380841 +0.0816659 -0.49717 0.209524 +-0.144856 0.495724 0.0887165 +0.0968155 0.506865 -0.0248881 +-0.00619353 0.506818 0.416667 +-0.0551665 0.494453 0.42718 +-0.400416 0.510471 -0.304226 +-0.343484 0.515537 -0.268083 +-0.400769 0.510392 -0.272387 +0.505171 -0.422307 0.288798 +-0.495804 0.462738 0.384976 +-0.482824 0.468677 -0.273549 +-0.492731 -0.444485 0.133612 +-0.0581982 0.489968 -0.450096 +-0.458225 0.477204 -0.23154 +0.304153 0.496284 0.434021 +0.504862 -0.261662 0.356546 +0.0969318 0.504926 -0.386449 +-0.511903 -0.364742 -0.424344 +0.508259 -0.293466 0.370338 +0.508993 -0.265479 0.387192 +0.323602 -0.17413 -0.501101 +0.494764 0.456627 -0.228963 +0.325674 -0.502583 0.214059 +0.29465 -0.499551 0.199162 +0.292327 -0.50773 0.233675 +0.204743 0.501768 -0.160115 +0.183182 0.508478 -0.0995956 +0.306555 -0.513129 0.0917675 +0.310873 0.10844 -0.511073 +0.239725 0.48203 -0.465804 +0.389009 -0.500227 0.0718229 +0.396085 -0.497636 0.140561 +0.404039 -0.508579 0.105861 +-0.295738 -0.179837 0.498243 +0.298773 -0.18449 -0.494093 +0.472984 0.462491 0.212922 +0.299517 -0.155253 -0.511068 +0.26425 0.474702 -0.48528 +0.0618967 0.505658 -0.424035 +-0.121188 0.442437 0.498325 +0.272073 0.489549 -0.468733 +0.0743051 0.503235 -0.398539 +-0.347782 -0.243399 0.497234 +0.051627 0.495536 -0.183737 +-0.100313 0.478367 -0.474037 +0.0831389 0.498058 -0.19461 +0.290759 0.511261 -0.364659 +0.0465251 0.413174 0.492786 +0.316285 0.50525 -0.377645 +-0.0500084 0.260465 0.493367 +0.508216 0.356007 0.22157 +0.509289 0.384606 0.219831 +0.475008 0.487014 0.177006 +0.514415 0.369087 0.191808 +0.419749 0.46441 0.489781 +-0.471564 -0.0961781 0.479388 +0.14635 -0.500468 -0.00317001 +0.167692 -0.507975 0.0354709 +0.17458 -0.501397 0.00921301 +-0.499058 0.00321982 0.22574 +-0.498723 0.0214192 0.198344 +-0.473023 -0.0689793 0.486526 +-0.503474 0.0363144 0.228425 +0.494842 -0.429463 -0.0398118 +-0.474132 -0.464604 0.283374 +-0.00531012 0.40834 0.507697 +-0.482224 -0.399546 0.459444 +-0.19422 0.492492 -0.222076 +0.0672268 -0.475029 -0.473329 +-0.170278 0.494268 -0.246762 +0.0975493 0.507226 0.288866 +-0.467642 -0.476518 -0.0894939 +0.00165972 0.505769 0.386625 +-0.411322 0.48023 -0.47265 +0.4538 0.397431 0.49471 +0.493479 -0.22868 -0.0785207 +0.471509 -0.140828 -0.466097 +0.497891 -0.189128 -0.0420349 +-0.0869201 0.43847 0.489607 +0.49989 -0.197808 -0.0699516 +-0.482201 -0.2107 0.46293 +-0.187504 -0.505012 0.100069 +-0.306783 0.499021 -0.180943 +-0.352751 0.505783 -0.20237 +-0.486081 0.4474 -0.45456 +-0.322845 0.499685 -0.209347 +0.219886 0.0585843 -0.491651 +0.185566 0.0554411 -0.495171 +0.488628 -0.425485 0.418604 +0.204877 0.0260789 -0.503274 +0.414152 0.0298737 0.504744 +0.0846868 0.500619 0.221495 +0.0381499 0.502571 0.239287 +-0.494789 0.436681 0.377187 +-0.513333 0.396678 0.356728 +0.509826 -0.184197 -0.370497 +0.492952 -0.126348 -0.402073 +-0.264613 0.498066 0.306073 +-0.284991 -0.372715 -0.513081 +0.0498265 0.382213 0.507223 +-0.0507101 0.493947 -0.0754461 +-0.400545 -0.505187 -0.388051 +0.181558 0.424048 -0.490849 +0.492961 0.320168 0.462482 +-0.433998 0.488942 0.374429 +0.168288 0.449505 -0.499511 +0.152307 0.430187 -0.507041 +-0.210623 0.50407 -0.370904 +-0.2132 0.495202 -0.042182 +-0.193508 0.491855 -0.0643518 +0.387105 0.513373 0.233958 +0.0910731 -0.497657 0.444884 +-0.177353 -0.508037 0.223873 +-0.244726 0.492767 -0.0508673 +-0.274217 0.495783 -0.0644041 +0.197818 0.187643 -0.501756 +-0.194752 -0.0121383 -0.494579 +-0.200485 -0.041864 -0.494369 +-0.173541 -0.0303879 -0.507471 +0.504681 0.330279 -0.285157 +0.516672 0.346297 -0.30699 +0.508348 0.300208 -0.281217 +0.0486167 0.506595 0.045062 +0.473995 -0.295268 0.479183 +-0.0886939 0.507101 0.0753353 +-0.450097 0.493606 0.121347 +0.155322 -0.494063 -0.241736 +0.487026 0.469586 -0.318196 +-0.400274 0.448888 -0.495233 +-0.509436 0.299316 0.433385 +-0.188691 0.499232 0.180795 +-0.147221 0.507636 -0.0840248 +-0.161436 0.49744 -0.104715 +-0.133593 0.500388 -0.114054 +-0.380639 0.509915 -0.129163 +-0.405515 0.506701 -0.146098 +-0.480314 0.130409 -0.467457 +-0.381273 0.508835 -0.160248 +0.433575 -0.487225 -0.193432 +-0.226463 -0.211941 0.505375 +0.448578 -0.497909 -0.217542 +0.427239 -0.508068 -0.217349 +0.398961 0.499305 -0.183829 +-0.150328 0.503076 0.226217 +-0.497481 -0.422723 0.453835 +0.233943 0.502186 0.18921 +-0.286529 0.498735 0.0656778 +-0.000276663 -0.228299 -0.494577 +-0.29167 0.508572 0.0444736 +-0.393959 -0.453521 -0.484103 +0.177839 0.500051 -0.4295 +0.504884 -0.399419 0.126955 +-0.470725 0.12541 -0.485811 +0.062492 -0.290902 0.500247 +-0.40163 0.494428 0.138857 +0.501049 -0.423465 0.151076 +0.512647 -0.392153 0.165251 +0.499653 0.37424 -0.192118 +0.50138 0.41567 -0.168999 +0.504724 0.413973 -0.23183 +-0.151265 0.492732 -0.0322172 +-0.132991 0.509036 -0.056764 +0.00648834 -0.198639 -0.502076 +-0.0864805 0.501433 -0.0257443 +-0.0747087 -0.126298 -0.500562 +0.0579573 -0.197077 -0.496478 +-0.202358 0.50106 -0.341935 +0.29877 -0.435212 0.510037 +-0.0796571 0.498316 0.461124 +-0.484485 0.109224 0.451572 +0.316787 0.507612 -0.195092 +0.268407 0.507186 -0.193496 +-0.234778 0.499153 0.385861 +0.129709 -0.437857 0.4855 +-0.245823 0.504973 0.354885 +0.202246 0.493592 -0.234855 +0.42667 0.499526 0.171174 +0.167859 0.5042 -0.242225 +-0.139227 0.501077 -0.330055 +-0.119336 0.499586 -0.300825 +-0.449376 -0.341266 0.501086 +-0.423062 -0.490629 -0.459527 +0.0223742 0.507329 -0.172499 +0.0186611 0.500053 -0.145736 +-0.00341297 0.492417 -0.160775 +0.239202 0.512287 -0.240732 +0.281023 0.497945 -0.244224 +0.211969 -0.275527 -0.495168 +0.258287 0.496509 -0.215383 +-0.0106573 -0.0701124 -0.502625 +0.216115 0.506137 -0.186454 +0.201108 0.497463 -0.206183 +0.502295 0.188194 -0.0630382 +0.345769 0.502841 -0.181251 +0.344582 0.515619 -0.240058 +0.45262 0.437233 -0.477833 +0.373825 0.508557 -0.168277 +-0.500092 0.313036 -0.266376 +-0.497605 0.150068 0.322332 +-0.505685 0.106951 0.271954 +-0.454273 -0.115441 0.485464 +-0.368623 0.511149 0.173701 +-0.396439 0.501776 0.166203 +0.216579 0.506935 0.327058 +-0.455219 -0.086582 0.49467 +0.429767 0.504945 0.0248138 +-0.508502 -0.363974 -0.146494 +0.349229 0.502222 -0.00575517 +0.023851 0.498765 0.0839424 +0.317769 0.512821 -0.0105405 +-0.314609 0.509872 0.402869 +-0.367354 0.497244 0.423258 +-0.326428 0.513598 0.377704 +-0.149887 -0.501239 0.230516 +-0.161055 -0.508189 0.279938 +-0.00904182 -0.315621 -0.512245 +-0.371867 -0.0851604 0.505785 +-0.142002 -0.509966 0.257763 +0.164431 -0.496083 0.370107 +-0.510358 0.334021 -0.240784 +0.181863 -0.50107 0.424923 +-0.272259 0.512921 -0.391299 +-0.283312 0.494015 -0.416239 +0.494092 0.174393 -0.222315 +-0.0781058 0.41233 0.496173 +-0.0333259 0.444622 0.505683 +0.480311 0.404055 0.464613 +-0.516433 0.324153 -0.293641 +0.483993 0.169875 0.442265 +-0.247144 0.502713 0.0415646 +-0.390472 -0.470789 0.482021 +-0.177702 0.50075 0.0881956 +0.0888159 -0.00280503 -0.49702 +0.0741413 0.0253929 -0.489938 +0.0568589 -0.00161824 -0.492147 +0.30477 0.373764 -0.50191 +-0.00131753 -0.0301743 -0.506047 +-0.0188829 0.508574 -0.295851 +0.502128 0.19193 -0.243337 +0.134251 0.406636 -0.497154 +0.0786673 0.508793 0.347244 +0.0461753 0.498821 0.330305 +0.0727298 0.503984 0.310326 +0.484872 0.461369 0.406946 +-0.489567 0.463912 0.182901 +-0.290199 0.456394 0.486746 +0.499328 -0.423253 -0.384252 +0.373214 -0.499871 -0.423039 +-0.301086 0.503475 0.339361 +-0.471353 -0.12358 0.472425 +-0.351892 0.518234 -0.373259 +-0.329752 0.515172 0.349841 +0.433069 -0.493386 -0.345453 +0.0825042 0.489752 -0.0792936 +0.0487589 0.489959 -0.0730119 +0.0601612 0.496845 -0.10348 +0.0888619 0.510158 -0.225714 +-0.452617 0.485389 -0.103698 +0.0999911 0.497142 -0.260379 +0.0956706 0.0121464 0.492745 +0.0850301 0.0400394 0.508907 +0.469183 0.194582 -0.48903 +0.126172 0.00884089 0.503862 +0.309144 0.501553 0.407104 +0.317874 0.51722 0.36312 +0.328184 0.514878 0.385866 +0.492342 0.127763 -0.449218 +0.111057 0.503097 0.0364618 +0.326618 0.505731 0.0866975 +-0.485881 0.437288 -0.192706 +0.359172 0.513505 0.0818785 +0.174142 0.498001 0.261197 +0.201316 0.499042 0.275314 +0.0389555 0.114695 0.498301 +-0.507282 0.418023 -0.380515 +0.144719 0.164836 -0.489771 +0.177462 0.170805 -0.503847 +0.154318 0.193913 -0.491061 +0.491823 -0.442218 -0.399033 +0.26408 -0.151881 0.510704 +0.277315 -0.0953218 0.501245 +0.179375 0.321299 0.500593 +0.171151 0.35261 0.511103 +-0.320754 -0.507223 -0.0844207 +0.20224 0.343772 0.50198 +0.506125 0.0142574 0.207659 +0.491861 -0.00897782 0.253579 +0.496375 0.0404713 0.220802 +0.257596 -0.175181 -0.494945 +0.474431 0.246312 0.468585 +0.25461 -0.234034 -0.501253 +-0.478533 -0.103742 0.458471 +0.296603 0.497454 0.192017 +0.39872 0.412511 0.493337 +0.0693623 0.100289 0.499132 +0.351861 0.397008 0.498475 +0.270001 -0.214903 -0.511756 +0.369895 0.421293 0.511844 +-0.331942 0.510302 0.26107 +0.500942 0.0110938 0.0725405 +-0.327593 0.496189 0.233743 +-0.340278 0.387426 0.509365 +-0.437755 0.133489 0.505614 +-0.465766 -0.352643 0.479814 +-0.408553 0.148042 0.494524 +0.509783 -0.292879 0.305441 +0.0396002 0.499291 0.264412 +-0.0203519 0.510958 0.321123 +-0.507803 -0.310162 -0.0867917 +-0.508741 -0.331401 -0.141954 +0.474949 0.432887 -0.481805 +-0.449716 0.482951 -0.389885 +-0.415643 0.512292 -0.378352 +-0.505341 -0.299899 -0.133894 +-0.037239 0.505537 -0.0473635 +-0.49396 0.383576 -0.431744 +-0.0559349 0.497433 -0.0237252 +-0.511118 0.320668 -0.211376 +0.193161 0.504464 -0.412136 +-0.0967064 -0.237351 0.502624 +-0.131609 0.490767 0.164569 +-0.179469 0.489356 0.158694 +-0.194325 0.504438 -0.137432 +-0.203546 0.494696 -0.0907808 +0.413377 0.496893 0.274452 +-0.442826 0.187722 0.49006 +-0.468019 -0.474189 0.223467 +-0.449984 -0.39601 0.484024 +0.205955 -0.0930222 0.494068 +-0.401898 -0.482743 -0.480052 +0.253399 -0.123534 0.505 +0.220241 -0.121521 0.495267 +0.440263 0.493133 -0.43071 +-0.0442814 0.50034 -0.126225 +-0.489076 -0.346296 -0.467115 +0.475251 -0.47818 -0.404925 +-0.0636774 0.491967 -0.103589 +0.510411 0.136668 0.24656 +0.500417 0.190109 0.184169 +0.505627 0.124643 0.194228 +0.450659 -0.494089 0.0810743 +0.345416 0.501609 -0.112359 +0.389186 0.513007 -0.0987094 +0.0669644 0.132514 0.501793 +-0.213033 0.507974 -0.116575 +-0.249444 0.505966 -0.0796403 +-0.267453 0.510235 0.0802714 +-0.00230567 0.495283 -0.0973645 +0.0145181 0.50034 -0.0705228 +-0.0187304 0.499024 -0.0722508 +0.354444 0.500393 -0.450695 +-0.457717 -0.449883 -0.485006 +0.468319 0.26004 0.481166 +0.444545 0.46615 0.47826 +-0.325731 0.512725 -0.128966 +-0.25649 0.505036 -0.146322 +0.0968877 -0.482749 -0.471554 +-0.269991 0.495561 -0.119949 +-0.128868 0.497652 -0.450721 +0.156352 0.495266 0.310819 +0.4935 0.201582 -0.217962 +0.44873 0.0881084 0.4899 +-0.466945 0.47597 -0.17024 +0.0795623 0.505691 0.0394845 +0.130994 0.490536 0.0619642 +-0.440614 0.353208 0.5036 +0.463817 0.475445 -0.451739 +-0.237092 0.494959 0.0674688 +-0.0762294 0.509593 0.268177 +-0.372224 -0.498668 0.267059 +-0.348135 -0.517313 0.254497 +-0.361278 0.506136 0.243757 +-0.414443 0.497973 0.257444 +0.245723 0.514861 -0.390803 +0.260424 0.496997 -0.410428 +0.474489 0.432447 0.463669 +0.282585 0.509921 -0.392339 +0.317906 0.49507 -0.110978 +0.289177 0.504112 -0.0612287 +-0.26304 0.0633642 0.495561 +0.287678 0.502933 -0.11072 +0.29167 0.505825 -0.282396 +0.496143 -0.438207 -0.445456 +0.245571 0.517184 -0.33592 +0.302824 0.499698 -0.316147 +0.345833 -0.434903 0.504183 +0.379075 -0.426443 0.504192 +-0.183105 0.257091 0.509072 +-0.242801 0.273864 0.510694 +-0.137771 -0.475198 0.473961 +-0.188273 0.286992 0.511604 +0.498591 -0.191783 -0.455207 +0.39672 0.515506 0.293636 +0.400714 0.501121 0.323514 +0.390764 0.512306 0.26404 +0.140111 -0.491165 0.247374 +-0.266673 0.496021 0.0547645 +0.101918 0.495303 -0.141312 +-0.460849 0.477615 -0.291272 +0.0695051 0.490481 -0.133129 +-0.245553 -0.498258 0.139824 +0.420916 -0.495484 -0.0374786 +0.0771342 0.501127 -0.163406 +0.43478 -0.503007 -0.0807066 +-0.0295693 0.492053 -0.172827 +-0.0594661 0.504498 -0.184032 +-0.0326273 0.490333 -0.20359 +-0.15963 0.506463 -0.213373 +-0.125643 0.505838 -0.204386 +0.453663 0.491054 0.343318 +0.513581 0.402667 0.0500775 +0.497761 0.415578 0.0257658 +0.0375156 0.490441 -0.00563163 +0.0347472 0.506039 -0.038289 +-0.499964 -0.404002 0.136444 +0.490895 0.0242052 -0.140737 +0.499502 0.00265395 -0.116832 +0.508329 0.0304614 -0.118693 +0.023238 -0.0621652 -0.508744 +0.348528 0.462861 -0.479122 +0.225313 0.502573 0.293673 +0.265173 0.51255 0.2508 +0.253689 0.503492 0.314922 +-0.430688 0.395507 -0.493992 +0.0516838 0.492999 0.219761 +-0.487001 0.445393 0.356168 +0.00791422 0.496619 0.192503 +0.0502992 0.495773 0.177614 +0.0127165 -0.0946721 -0.498414 +0.172912 0.500226 -0.0674119 +0.182008 0.497104 -0.00947236 +0.515279 0.322597 -0.350979 +0.482745 0.461249 -0.462236 +0.455 -0.474776 0.476691 +-0.214226 -0.344311 -0.505967 +-0.478317 0.202746 0.483238 +0.503736 -0.425145 0.208152 +-0.478339 -0.422912 0.468972 +0.456221 -0.371649 -0.496435 +-0.473082 0.176213 0.479464 +0.357203 0.484822 0.45027 +0.361221 0.48048 0.473767 +0.509534 -0.40196 0.20107 +0.472331 0.123442 0.463673 +0.469577 -0.327669 -0.48134 +-0.430553 -0.467914 -0.468133 +-0.466625 0.458239 0.460517 +0.482411 0.479961 -0.346031 +0.462718 0.456984 -0.464586 +0.470306 -0.46933 0.312058 +-0.46654 -0.466945 -0.457771 +3 2152 2918 962 +3 1251 3834 569 +3 2145 2917 782 +3 3923 3900 4739 +3 20 3070 2765 +3 3979 3932 2302 +3 3349 1139 178 +3 317 3597 2299 +3 23 4245 2359 +3 4747 3471 37 +3 7044 1657 2786 +3 1754 1677 1680 +3 4003 3999 320 +3 988 1269 3027 +3 4081 4041 450 +3 0 248 51 +3 2134 4116 5115 +3 2133 1769 7297 +3 285 741 1888 +3 2823 29 108 +3 316 4316 12 +3 2797 20 7093 +3 18 7 669 +3 4355 4343 2649 +3 3693 2127 4380 +3 2126 4393 6754 +3 3131 38 182 +3 2123 2911 7229 +3 4517 4491 5004 +3 4594 2910 2859 +3 44 2362 4315 +3 2100 4674 6888 +3 4693 5666 7443 +3 2097 4778 1109 +3 39 6007 186 +3 4870 4825 2511 +3 38 3257 206 +3 220 43 2224 +3 2983 5021 4439 +3 1336 4972 1411 +3 3834 5055 954 +3 3025 2401 2109 +3 5095 5069 2087 +3 6736 7 1591 +3 5136 2083 79 +3 744 59 232 +3 243 419 2239 +3 2049 4201 377 +3 2151 5869 2149 +3 485 5270 6117 +3 12 9 4282 +3 53 2318 940 +3 4282 9 6617 +3 5285 1058 6605 +3 2029 2988 4708 +3 5344 5327 56 +3 12 4282 316 +3 5418 5412 7022 +3 2067 5477 165 +3 2008 266 2256 +3 5562 7281 6302 +3 5647 2901 181 +3 57 2260 58 +3 2901 5666 4693 +3 2900 7367 2076 +3 270 64 2262 +3 1888 3597 285 +3 313 1114 1028 +3 65 5772 5755 +3 3 2480 3943 +3 2480 3 4793 +3 2211 203 364 +3 9 12 2935 +3 5564 4 389 +3 5115 4116 5698 +3 389 4 3004 +3 5756 5727 2511 +3 5787 5785 4866 +3 4461 6435 7 +3 67 2092 399 +3 2159 6 419 +3 419 6 2239 +3 317 2277 3597 +3 2354 428 429 +3 2694 147 7033 +3 155 4078 5643 +3 23 442 7506 +3 7506 442 8 +3 2039 7006 1143 +3 6053 6022 1328 +3 6109 6105 4657 +3 952 3744 3811 +3 2318 53 2280 +3 2169 2304 509 +3 1739 6246 6147 +3 6327 6310 5862 +3 2036 6339 45 +3 152 6338 6429 +3 551 46 4523 +3 4541 564 408 +3 6506 50 7091 +3 2531 3257 3256 +3 5120 49 4747 +3 657 89 4752 +3 2423 2348 657 +3 2362 44 2105 +3 44 4368 2101 +3 6586 6575 1625 +3 5559 2049 377 +3 2442 78 2445 +3 497 4384 2382 +3 496 4893 5365 +3 4282 6654 1931 +3 742 80 743 +3 1493 47 4616 +3 2160 2235 3726 +3 47 748 2102 +3 6702 6665 1308 +3 1743 76 2835 +3 147 5790 5789 +3 2024 6724 1652 +3 4933 83 760 +3 6833 6832 5940 +3 6923 6896 2727 +3 7011 6952 2463 +3 2453 83 4931 +3 2835 76 7305 +3 1169 4004 7035 +3 79 5153 1278 +3 5153 79 2276 +3 7065 7062 145 +3 796 2051 5671 +3 84 3210 4849 +3 836 34 2385 +3 2190 49 5120 +3 7113 6064 544 +3 84 3208 3670 +3 5082 2259 5208 +3 2017 7140 2170 +3 61 19 2503 +3 4375 6555 5824 +3 3057 7240 119 +3 2503 19 2198 +3 4893 4896 645 +3 2006 7294 2415 +3 5383 91 2309 +3 91 5429 995 +3 6763 92 6152 +3 2556 93 1036 +3 7418 7369 5555 +3 104 5375 115 +3 1123 1053 1050 +3 7264 7503 1736 +3 7038 1546 4096 +3 2250 1050 1053 +3 5592 95 5595 +3 5132 2500 5133 +3 5375 104 4760 +3 1965 1994 52 +3 4186 4056 3736 +3 2504 90 5213 +3 2565 95 5591 +3 424 3143 2198 +3 71 4287 4294 +3 5805 3043 5366 +3 4451 2710 1335 +3 1139 51 178 +3 4947 3844 3389 +3 1979 4740 7306 +3 1618 191 7523 +3 1124 3321 5242 +3 936 5260 1348 +3 4691 2880 112 +3 2351 115 5418 +3 6065 1188 1191 +3 224 2429 1192 +3 4935 4915 4834 +3 6009 97 1229 +3 2635 97 1230 +3 43 1130 1244 +3 567 3982 1525 +3 39 609 5748 +3 5418 115 5412 +3 1347 6278 2682 +3 6374 100 1378 +3 100 1379 6168 +3 6479 112 2533 +3 3685 5107 3117 +3 5203 5103 6948 +3 7240 1207 4459 +3 6446 101 1926 +3 1440 6460 5809 +3 2323 119 7240 +3 119 7237 3057 +3 1570 1178 2635 +3 5250 2533 5394 +3 52 5389 2577 +3 2752 103 6805 +3 3736 6657 2874 +3 1641 20 2765 +3 1600 1598 7380 +3 3930 3360 610 +3 120 6276 959 +3 5565 4061 6938 +3 7044 1798 29 +3 7285 30 29 +3 7024 30 2783 +3 1680 105 1754 +3 6276 120 6861 +3 6726 6571 4812 +3 3722 6894 5908 +3 7145 7014 2107 +3 7067 109 1689 +3 2797 107 3070 +3 1953 2869 870 +3 3845 1496 7105 +3 1338 4824 7182 +3 75 411 2383 +3 2732 102 3982 +3 7435 7313 640 +3 2376 4377 491 +3 1277 2633 21 +3 3883 4159 4920 +3 1277 21 7165 +3 4035 6899 5537 +3 2360 23 4246 +3 1087 6470 6051 +3 123 1942 6878 +3 6973 1756 1757 +3 108 7249 1773 +3 2233 26 1790 +3 5124 4928 5037 +3 2886 5425 3869 +3 1790 26 2243 +3 2820 27 252 +3 252 2675 2820 +3 7247 1798 2786 +3 1798 7247 108 +3 108 29 1798 +3 2783 30 1800 +3 2830 109 7310 +3 1942 123 6880 +3 1874 7413 2227 +3 2324 5270 4755 +3 2850 110 7412 +3 6117 1078 5067 +3 96 1154 6215 +3 132 150 7442 +3 2675 99 1897 +3 1932 5044 2905 +3 2107 7014 6641 +3 1932 111 2095 +3 7078 2536 6150 +3 2870 2095 111 +3 7078 7147 1953 +3 2799 1965 2052 +3 1967 2877 870 +3 7496 127 1920 +3 2710 101 6445 +3 2040 2039 2132 +3 2053 5593 2901 +3 169 3072 2180 +3 2330 33 2092 +3 2092 33 2355 +3 2095 6150 1932 +3 6922 6871 5763 +3 1316 2108 4550 +3 127 7347 7495 +3 6127 3893 7512 +3 7447 1890 1893 +3 5115 1890 2134 +3 828 2351 2263 +3 6008 5754 1940 +3 7429 2301 2246 +3 2300 129 7419 +3 3015 1611 2170 +3 2171 6112 1282 +3 5366 3043 827 +3 161 879 2173 +3 704 902 4826 +3 7077 6722 1120 +3 3054 209 5114 +3 2178 34 836 +3 1931 316 4282 +3 1928 7504 6482 +3 1922 7501 1408 +3 3070 1692 2765 +3 2765 6826 1641 +3 2180 2178 3242 +3 2180 3071 169 +3 7496 6483 3281 +3 1416 36 3328 +3 129 7420 198 +3 7490 7491 5031 +3 16 4316 7488 +3 3106 759 2185 +3 390 3119 2189 +3 1139 3349 223 +3 838 37 5521 +3 5521 37 114 +3 1910 1972 4534 +3 3131 5473 2193 +3 267 3132 2195 +3 6007 39 5748 +3 5177 133 3374 +3 3895 4355 7482 +3 189 3850 6637 +3 3374 133 3525 +3 6703 227 1544 +3 364 203 839 +3 3257 38 2193 +3 3256 3257 2193 +3 1288 3273 2219 +3 213 211 2220 +3 276 3319 579 +3 2224 3321 220 +3 3436 6894 5524 +3 2224 43 1244 +3 5242 3321 2224 +3 2068 224 1192 +3 5277 3360 3930 +3 2136 3373 2231 +3 6344 189 1382 +3 806 3412 891 +3 7479 7480 2197 +3 2237 46 551 +3 235 46 2237 +3 3433 1580 2238 +3 7472 7474 486 +3 245 2245 2459 +3 1263 7468 6976 +3 49 0 3471 +3 150 132 4772 +3 114 51 1139 +3 136 3380 4977 +3 2253 973 6896 +3 6233 199 7487 +3 2583 788 5709 +3 136 1037 4381 +3 54 1595 2256 +3 7359 140 7357 +3 1905 7463 4822 +3 2275 6723 176 +3 3597 1888 743 +3 7357 140 2572 +3 7334 141 7335 +3 3625 1707 1856 +3 141 2723 5936 +3 3648 552 2287 +3 3726 59 744 +3 2299 5222 317 +3 1377 64 270 +3 1348 3778 936 +3 2470 3792 2305 +3 148 3428 3113 +3 1032 3840 2312 +3 3845 3844 5792 +3 3428 148 3426 +3 2491 7458 6147 +3 349 3864 2317 +3 2320 66 65 +3 3965 1059 2579 +3 2322 4547 567 +3 7288 151 7292 +3 7292 151 244 +3 7111 843 1708 +3 2092 67 2330 +3 252 1898 2857 +3 1562 680 2209 +3 7448 7449 5046 +3 2655 411 1001 +3 413 1255 2342 +3 921 2914 2855 +3 1889 7444 286 +3 199 1120 7488 +3 429 428 3445 +3 2359 4246 23 +3 449 4255 2361 +3 2251 1428 7276 +3 7443 415 2906 +3 462 1716 2366 +3 2854 7438 2484 +3 2374 1224 470 +3 716 4358 970 +3 4373 1217 2376 +3 2491 250 7458 +3 7458 250 48 +3 535 4412 2384 +3 158 378 2308 +3 3671 284 7429 +3 7433 4212 6540 +3 2392 4481 2729 +3 7238 1149 173 +3 7422 7423 3086 +3 2300 2372 7430 +3 1995 1546 7038 +3 1878 7416 1898 +3 560 1584 561 +3 1416 4541 6420 +3 1416 2401 4541 +3 572 4563 2402 +3 980 4615 1868 +3 4627 1388 2407 +3 609 1296 2411 +3 237 6954 9 +3 179 173 7236 +3 173 1149 7073 +3 284 7430 7045 +3 2197 3923 7408 +3 114 37 3471 +3 657 7303 2423 +3 2271 5511 6811 +3 4785 4454 332 +3 2815 179 7235 +3 4816 937 2088 +3 1870 7405 7355 +3 7235 179 7236 +3 931 4856 2440 +3 7510 4160 4691 +3 3426 309 3390 +3 4914 2102 748 +3 497 1660 4896 +3 2450 741 4988 +3 743 80 2451 +3 7400 6644 1975 +3 2452 746 4913 +3 755 4923 2125 +3 5433 7399 1263 +3 4931 83 4933 +3 766 4937 2457 +3 767 1183 1007 +3 4425 180 1762 +3 180 7023 1309 +3 2372 2300 7419 +3 986 4948 2462 +3 7209 1550 2246 +3 2241 2301 7157 +3 1442 5051 2226 +3 6910 5107 3685 +3 5120 89 857 +3 857 89 657 +3 2214 190 7055 +3 5171 1468 2560 +3 5195 1071 2501 +3 5213 90 5212 +3 2881 7395 6157 +3 894 5220 1284 +3 7055 190 3299 +3 7212 685 1680 +3 2507 908 2936 +3 685 2241 7158 +3 941 1031 3765 +3 946 5283 3967 +3 1467 1285 4147 +3 2935 4269 7391 +3 3390 309 4388 +3 2844 1408 7060 +3 1842 5322 2148 +3 1223 5333 2526 +3 6644 3883 7379 +3 6926 1780 1624 +3 5372 4261 6098 +3 5394 917 5250 +3 5400 1094 1552 +3 7335 312 7334 +3 5429 91 2532 +3 1008 5447 2081 +3 1022 5489 3930 +3 312 6683 293 +3 226 325 7254 +3 1036 331 2556 +3 1036 93 2558 +3 4602 7446 2268 +3 1783 202 1631 +3 1046 1420 5190 +3 1053 1123 5575 +3 95 2568 3513 +3 867 1072 2575 +3 1821 212 4672 +3 424 4758 1390 +3 202 3078 6232 +3 1397 5764 2232 +3 5585 5237 7068 +3 1130 1245 2589 +3 5712 1131 1244 +3 1658 1661 2599 +3 1150 5861 2600 +3 1857 2843 2483 +3 1629 229 6938 +3 105 143 2804 +3 2420 296 3587 +3 1848 7361 3963 +3 1051 7356 2264 +3 1870 7355 964 +3 1185 5923 2614 +3 7350 7351 5148 +3 229 4022 4 +3 2131 1201 6873 +3 6688 234 6873 +3 1230 97 6009 +3 7346 7347 5442 +3 2839 1515 1793 +3 6873 234 6870 +3 1834 7339 1987 +3 2642 6054 6455 +3 220 222 2643 +3 186 3157 2656 +3 312 7335 1004 +3 2658 2228 6193 +3 6954 237 6955 +3 1322 1360 2668 +3 1334 6255 2674 +3 3736 4056 7333 +3 7328 7329 1120 +3 1897 99 6445 +3 6261 1847 2678 +3 2682 976 1347 +3 1370 6330 2686 +3 5700 7323 2811 +3 1379 100 6374 +3 1389 6385 2695 +3 1737 7176 6407 +3 1405 6415 5928 +3 1425 6434 2706 +3 2707 6876 6438 +3 6446 1927 2711 +3 7315 7316 1861 +3 6445 101 2711 +3 2273 2543 5463 +3 1461 6497 2716 +3 244 238 6821 +3 1571 1487 2726 +3 1507 1503 6591 +3 6821 238 6634 +3 3982 102 2735 +3 1540 6689 4301 +3 5978 2141 7385 +3 6820 244 6821 +3 6805 6804 2752 +3 176 1588 2757 +3 1606 6864 5487 +3 238 244 151 +3 2786 1798 7044 +3 6798 251 1344 +3 5853 2791 1754 +3 1754 105 5853 +3 2793 7338 1833 +3 2047 1879 2795 +3 3070 107 2798 +3 7507 3634 1576 +3 3587 296 5821 +3 251 6798 2313 +3 2832 4590 7355 +3 1989 1069 4186 +3 1825 2796 42 +3 1781 74 2378 +3 7307 7308 4328 +3 1838 7346 5442 +3 1774 7246 1776 +3 1786 2819 4854 +3 1344 337 6798 +3 3434 866 7129 +3 5382 1806 2824 +3 1809 5572 4253 +3 7338 7089 2833 +3 2833 1835 7338 +3 1857 7365 5587 +3 594 7399 5433 +3 1815 7299 6906 +3 659 279 3612 +3 1865 7384 6680 +3 279 6715 5373 +3 1978 7396 2846 +3 7412 110 2851 +3 6693 291 6695 +3 2028 7283 2069 +3 291 5530 5528 +3 2533 112 2880 +3 112 2657 4691 +3 2901 5647 2053 +3 4253 1811 1809 +3 2905 4729 1932 +3 2910 4594 2108 +3 253 7288 7292 +3 2123 4455 2911 +3 4118 2855 2914 +3 1800 7286 6520 +3 2145 3838 2917 +3 2918 2152 2 +3 2079 293 6683 +3 7254 325 434 +3 2262 269 58 +3 3788 146 509 +3 839 1054 364 +3 329 40 4465 +3 4021 1046 5564 +3 446 400 595 +3 243 2116 419 +3 2278 2299 3597 +3 1099 427 429 +3 1214 2237 551 +3 4469 7276 7021 +3 496 2255 647 +3 1264 1791 4854 +3 7254 434 7253 +3 7253 434 28 +3 1782 7269 1273 +3 1772 7265 3489 +3 7260 7261 3813 +3 743 2451 2278 +3 2454 2415 4931 +3 7257 7258 2937 +3 71 4294 2073 +3 325 226 6429 +3 1962 7266 7250 +3 564 4541 729 +3 2477 2178 836 +3 293 3922 7012 +3 106 294 5985 +3 1771 1273 7261 +3 5705 3613 2259 +3 2183 2260 57 +3 3360 3424 6853 +3 5089 3634 7441 +3 5420 1165 5419 +3 3044 5464 6723 +3 2549 1027 5512 +3 2239 2330 67 +3 3513 5591 95 +3 548 2359 4245 +3 7235 7236 2144 +3 1767 7233 3359 +3 1123 4256 3701 +3 1139 223 3217 +3 1125 2320 65 +3 7226 7230 6267 +3 7421 7221 1563 +3 1759 1543 1085 +3 650 3501 1148 +3 6248 301 3654 +3 2365 86 796 +3 687 2068 1192 +3 2637 1227 1230 +3 1131 2224 1244 +3 3654 301 6984 +3 6198 1296 1297 +3 6634 302 6633 +3 2692 4505 6168 +3 1755 6761 1782 +3 7213 7215 4917 +3 7209 7210 6031 +3 6380 1380 2329 +3 2439 455 3109 +3 2532 91 5383 +3 1520 2731 1524 +3 116 6706 1670 +3 7206 7207 1866 +3 3109 455 2847 +3 492 7238 179 +3 6703 537 6705 +3 6706 116 3087 +3 6633 302 3470 +3 1570 1227 4898 +3 6777 1577 1578 +3 6804 2753 5855 +3 2765 1597 6826 +3 6847 3238 6845 +3 5107 5108 6405 +3 2798 1692 3070 +3 6705 537 6551 +3 2735 1525 3982 +3 2609 2791 5853 +3 4308 607 4307 +3 2359 2321 4246 +3 7195 3161 2588 +3 635 6567 882 +3 634 228 1790 +3 2786 117 7247 +3 7247 117 3812 +3 7191 7192 532 +3 198 7420 7188 +3 1709 1609 70 +3 5558 2793 1619 +3 2814 3962 7467 +3 4984 5396 3213 +3 3068 3666 1090 +3 1740 192 1749 +3 2677 1794 1897 +3 7468 1263 7467 +3 314 6574 1326 +3 7177 7180 4284 +3 2711 1434 6445 +3 1080 2877 1992 +3 6906 3015 1817 +3 7113 2032 7116 +3 6574 314 1678 +3 790 399 2092 +3 7147 7078 2095 +3 4380 4374 3693 +3 2235 2294 617 +3 1093 2579 5962 +3 5872 4748 2423 +3 2786 904 1970 +3 2782 2905 5044 +3 3663 1603 2596 +3 7470 122 3132 +3 1121 2921 3591 +3 2037 1530 2923 +3 2932 313 6166 +3 315 6568 6923 +3 1402 4595 5469 +3 1831 585 2938 +3 2811 2598 5700 +3 1075 5645 5877 +3 2940 5877 6380 +3 6191 367 1189 +3 2457 763 2941 +3 2942 6443 7016 +3 2943 457 4271 +3 2085 2160 744 +3 744 232 2085 +3 2085 232 5095 +3 443 2378 5408 +3 6568 315 321 +3 6568 321 3699 +3 3699 321 6249 +3 7289 2944 128 +3 6758 4182 7043 +3 992 835 5080 +3 427 367 2960 +3 3203 3123 3429 +3 2965 174 4296 +3 457 174 4271 +3 2997 3224 2974 +3 2974 3224 2976 +3 1728 7168 7500 +3 635 995 5429 +3 913 326 3700 +3 3211 6394 3376 +3 2977 579 3633 +3 1923 7166 5706 +3 5909 1016 2979 +3 326 3704 4861 +3 626 2436 5032 +3 800 2722 7425 +3 1038 1438 2987 +3 3945 139 205 +3 205 278 3945 +3 1277 5942 5312 +3 576 1977 6544 +3 142 4513 2166 +3 642 1325 6527 +3 4702 1615 6912 +3 651 642 6527 +3 3186 754 157 +3 7161 7162 5630 +3 1969 565 6528 +3 31 4681 5604 +3 2301 2241 685 +3 1720 7152 4345 +3 332 1458 4785 +3 1325 642 2279 +3 1417 408 6418 +3 3895 7482 7142 +3 388 7478 2480 +3 3508 388 4021 +3 3008 446 4254 +3 1352 416 3011 +3 1481 2932 509 +3 2932 2169 509 +3 509 146 1481 +3 2281 2292 1481 +3 711 3559 3936 +3 3015 6906 6870 +3 7134 7135 4350 +3 1652 280 6626 +3 332 4784 4926 +3 1644 352 3032 +3 1902 7131 2229 +3 4007 2545 5490 +3 7125 7126 3896 +3 155 3035 3295 +3 7451 7123 6584 +3 7349 6408 376 +3 209 210 1209 +3 4439 2189 521 +3 6798 337 6472 +3 1282 157 3033 +3 337 5626 3689 +3 4981 358 3759 +3 2937 7477 7118 +3 5739 159 3043 +3 159 2226 3339 +3 7114 5249 2295 +3 288 161 2173 +3 1969 651 6525 +3 651 6527 1155 +3 288 167 166 +3 167 1444 467 +3 2396 2600 4504 +3 358 988 3760 +3 2175 1764 7096 +3 7096 5955 2175 +3 2276 2296 575 +3 6981 2116 3048 +3 853 2219 3054 +3 3276 362 1417 +3 362 6417 4980 +3 3070 20 2797 +3 1111 169 3071 +3 34 2178 3072 +3 3072 2178 2180 +3 5549 2177 3072 +3 3328 2401 1416 +3 3328 36 2225 +3 36 6420 2064 +3 7109 7111 7095 +3 170 3074 6447 +3 3074 170 1706 +3 3076 2961 1295 +3 7107 7106 2328 +3 2882 7101 7504 +3 3255 1631 202 +3 7097 7098 6447 +3 1826 1025 6378 +3 7090 7093 2221 +3 666 2183 2425 +3 2155 363 6478 +3 457 3087 4296 +3 175 3095 3816 +3 1539 662 1987 +3 712 1976 2681 +3 3098 1216 6337 +3 3098 3097 3099 +3 666 668 3101 +3 1151 2454 3106 +3 759 760 3111 +3 4690 521 5259 +3 391 5278 3119 +3 2326 390 3120 +3 6967 6301 6971 +3 1701 7081 6293 +3 3349 178 6363 +3 2970 1477 6531 +3 365 6370 1820 +3 2801 68 7079 +3 2702 1404 2580 +3 2580 3130 2702 +3 1382 2192 6344 +3 3042 1603 3263 +3 6370 365 4248 +3 7070 7071 1017 +3 38 3131 2193 +3 3131 182 1016 +3 183 3132 267 +3 662 1919 4028 +3 1692 2798 435 +3 3132 183 1121 +3 184 3136 1106 +3 3136 184 267 +3 1693 375 365 +3 2306 329 3138 +3 1579 6311 4841 +3 3141 6751 5372 +3 185 2504 3143 +3 1390 185 3143 +3 3416 701 3151 +3 1687 3489 1986 +3 3153 2085 5095 +3 186 6007 4626 +3 3158 4077 4378 +3 840 187 3164 +3 7063 181 4687 +3 3164 187 1457 +3 3323 2787 5575 +3 2113 933 4517 +3 365 375 1108 +3 384 6369 1693 +3 2970 1382 189 +3 6369 384 5410 +3 2069 2047 2795 +3 3188 4461 6551 +3 456 3194 6749 +3 724 401 6335 +3 401 2966 593 +3 190 2214 887 +3 3200 839 5093 +3 193 3204 3423 +3 3204 193 6742 +3 770 414 6323 +3 6027 7253 7052 +3 194 4536 2489 +3 2390 40 2202 +3 6323 6322 770 +3 3207 347 3861 +3 417 6291 770 +3 6291 417 706 +3 1399 200 2207 +3 200 3019 2207 +3 1399 3020 200 +3 3115 3103 3221 +3 408 564 1415 +3 212 6479 3594 +3 448 6281 2168 +3 6281 448 4042 +3 1674 1676 1675 +3 674 5480 2701 +3 3225 3224 3226 +3 619 606 3229 +3 1216 328 5981 +3 3231 328 6790 +3 195 339 3238 +3 2568 1054 3244 +3 117 52 1994 +3 6174 451 6175 +3 2217 207 3244 +3 557 476 1363 +3 207 675 3250 +3 3250 130 4780 +3 839 203 5093 +3 678 6358 6362 +3 6888 4674 7036 +3 1634 1666 3947 +3 6358 678 5826 +3 6707 2584 5732 +3 4572 206 3257 +3 306 4875 7463 +3 1363 476 1110 +3 41 675 2217 +3 799 463 5941 +3 6071 675 41 +3 2712 722 6353 +3 139 2188 3267 +3 210 209 3273 +3 6169 210 3273 +3 3085 2944 3274 +3 2435 227 3275 +3 1944 1269 3276 +3 5289 213 3279 +3 5401 5318 7026 +3 1839 529 4230 +3 722 5687 2098 +3 3282 3223 211 +3 211 213 3282 +3 3164 3206 3287 +3 7020 7021 622 +3 2296 2083 3288 +3 3287 3286 3288 +3 463 5944 515 +3 216 215 3291 +3 3291 215 5289 +3 3292 3199 1723 +3 1583 1750 466 +3 529 4229 828 +3 215 216 2222 +3 7327 3047 3296 +3 6039 1010 4189 +3 2217 1010 41 +3 724 6332 1863 +3 5456 41 1010 +3 466 5866 1583 +3 7003 4726 3443 +3 1564 4591 791 +3 4261 5372 6751 +3 6997 2515 27 +3 6924 1239 6751 +3 6040 1044 1239 +3 422 276 3318 +3 3319 3561 1443 +3 4834 4915 6995 +3 6993 6038 3724 +3 1736 7503 6991 +3 219 4605 579 +3 6332 724 6334 +3 1069 2201 2172 +3 222 220 3321 +3 6984 6985 7108 +3 222 3321 2627 +3 3059 3060 3324 +3 3327 2910 1316 +3 5866 466 6077 +3 2109 2401 3328 +3 3337 5367 6711 +3 3338 426 4445 +3 7036 6979 1990 +3 3339 3043 159 +3 1055 573 4236 +3 3060 3093 3350 +3 3351 3350 3352 +3 3315 3040 3354 +3 224 2068 2263 +3 6677 104 2351 +3 6972 6974 3284 +3 2951 2966 3361 +3 3362 1475 502 +3 3369 1352 6285 +3 2162 271 3371 +3 3999 2361 3373 +3 1127 1128 3381 +3 1354 363 982 +3 6971 6301 3303 +3 3897 1235 350 +3 3387 171 3897 +3 3381 3019 3389 +3 2233 1790 228 +3 740 6318 69 +3 228 280 2233 +3 6962 6964 1512 +3 280 228 3581 +3 6958 6960 2009 +3 6954 6955 7199 +3 5792 477 1147 +3 6660 6953 3306 +3 6344 3850 189 +3 3402 3058 1207 +3 4277 230 3406 +3 1636 6951 5466 +3 1632 6946 3149 +3 230 2755 5119 +3 373 7060 6944 +3 3408 3407 1103 +3 2775 7190 7351 +3 1629 6938 4061 +3 3726 744 2160 +3 1861 7316 6934 +3 477 3020 5791 +3 3412 233 5210 +3 354 235 3413 +3 6931 6932 1732 +3 3414 4523 46 +3 3956 7144 6929 +3 46 235 3414 +3 2973 2972 3419 +3 3360 1668 3424 +3 3390 3332 3426 +3 3113 3166 148 +3 6927 3687 1780 +3 573 1291 4436 +3 6920 6921 616 +3 1399 236 3431 +3 3431 236 2476 +3 3617 5060 6919 +3 263 6617 6917 +3 1622 6915 4702 +3 665 493 3036 +3 493 4079 4735 +3 2713 6911 6910 +3 3895 7142 6909 +3 494 5722 5725 +3 239 4323 717 +3 3364 6907 6905 +3 240 3433 239 +3 3433 240 2738 +3 2239 67 243 +3 7084 7168 4199 +3 4285 6900 6898 +3 918 1738 3992 +3 1254 1097 3437 +3 2574 3323 4038 +3 121 1714 3455 +3 1790 2243 634 +3 6892 6893 1664 +3 3455 3454 3456 +3 3456 634 4714 +3 3270 3104 3466 +3 5722 494 4976 +3 2245 245 246 +3 5839 246 245 +3 6889 6890 4267 +3 495 2316 1516 +3 3471 0 51 +3 51 114 3471 +3 7166 495 5706 +3 502 5648 3362 +3 502 1877 1371 +3 3475 2021 5874 +3 7187 253 3476 +3 423 6940 1575 +3 2104 691 5325 +3 3476 253 1803 +3 1620 5571 2324 +3 3482 3382 6026 +3 4906 6876 2707 +3 3484 970 3201 +3 3585 978 5010 +3 5206 4887 6875 +3 507 1365 5625 +3 3490 1611 234 +3 1612 2522 1672 +3 2384 255 3491 +3 3491 255 2261 +3 6869 6870 6906 +3 1606 5487 5346 +3 3488 259 3492 +3 3492 259 1913 +3 2254 1148 3501 +3 1148 2254 5794 +3 3081 3420 3498 +3 3501 2988 2029 +3 2342 2917 2140 +3 6853 6854 610 +3 6849 6851 5397 +3 260 404 261 +3 260 271 2162 +3 5032 2436 3651 +3 261 3502 475 +3 3502 261 404 +3 3238 6847 4676 +3 277 388 3508 +3 388 277 2875 +3 3354 3353 3511 +3 2256 266 647 +3 2255 54 2256 +3 2256 647 2255 +3 527 507 5625 +3 469 4882 3018 +3 6835 6838 677 +3 1365 507 1344 +3 1601 1996 3247 +3 1510 526 5622 +3 3519 2761 54 +3 2766 1511 3587 +3 526 3785 3541 +3 54 2255 3519 +3 267 184 183 +3 184 3520 183 +3 1508 527 5622 +3 322 268 3757 +3 3523 268 4723 +3 3375 3374 3525 +3 268 322 1488 +3 527 5625 1510 +3 2922 817 3529 +3 2608 1165 3529 +3 58 269 57 +3 1597 2765 1692 +3 1596 6823 4146 +3 2262 58 270 +3 189 3535 2970 +3 3539 404 260 +3 6673 7292 244 +3 3539 3538 1061 +3 3017 3461 3542 +3 272 3549 1455 +3 3549 272 3555 +3 5311 273 3549 +3 3549 273 3550 +3 6477 274 3550 +3 274 2083 5136 +3 1477 2187 6533 +3 3503 3504 3551 +3 3500 2091 3553 +3 530 5569 2562 +3 3556 563 2527 +3 2266 6307 982 +3 1594 2327 5160 +3 5569 530 6471 +3 982 1764 2266 +3 3319 276 3561 +3 1964 6812 6811 +3 48 7448 6809 +3 5515 7202 7522 +3 1588 176 6723 +3 3419 3418 3565 +3 3333 277 3508 +3 4297 3228 6121 +3 539 5540 1695 +3 2250 1052 5498 +3 3563 3562 3574 +3 3577 599 2048 +3 539 1435 1105 +3 6221 544 5525 +3 278 599 3005 +3 6802 2604 1645 +3 5525 544 547 +3 421 6796 251 +3 3581 6289 583 +3 661 613 3583 +3 3124 3123 5037 +3 2182 2272 281 +3 691 3163 2279 +3 2467 718 2067 +3 6064 547 544 +3 2751 2848 6786 +3 3592 2125 6585 +3 547 4645 3451 +3 5495 1105 1435 +3 740 3687 6927 +3 5970 5584 2273 +3 2855 3600 3012 +3 240 6783 2738 +3 285 3597 2277 +3 2277 286 285 +3 2428 1486 425 +3 285 286 7444 +3 167 288 2173 +3 3511 3512 3604 +3 2357 439 3610 +3 1426 887 5454 +3 5082 5705 2259 +3 553 4206 1478 +3 3613 290 2018 +3 2018 2259 3613 +3 4206 553 829 +3 2888 2283 3843 +3 476 557 7007 +3 2466 788 3619 +3 6778 6779 3854 +3 1912 3487 7390 +3 2583 5709 465 +3 1577 6777 188 +3 6772 6774 4812 +3 465 3620 2583 +3 3618 2670 5192 +3 6768 1813 1605 +3 58 2260 3621 +3 3766 6835 6764 +3 2402 571 3621 +3 7007 3902 476 +3 3625 7109 1707 +3 3630 4945 2843 +3 4204 3630 2284 +3 1418 2013 3635 +3 6528 565 5324 +3 1418 295 619 +3 295 7290 606 +3 1258 1070 3642 +3 2722 800 7494 +3 6753 6755 4542 +3 886 5424 2530 +3 3648 4528 137 +3 1564 6751 3141 +3 3309 3308 3650 +3 3650 795 4886 +3 2596 1603 6545 +3 6745 6746 5483 +3 3003 3246 3653 +3 2200 299 3658 +3 3658 299 4357 +3 6741 6742 410 +3 1110 3126 3832 +3 4979 359 3936 +3 4449 4567 5324 +3 2730 355 3667 +3 5874 576 5321 +3 3670 3210 84 +3 414 770 6291 +3 303 3678 2288 +3 3678 303 606 +3 304 585 2288 +3 304 3676 585 +3 5321 576 6544 +3 868 592 4247 +3 592 824 2176 +3 2933 305 3868 +3 6737 6739 2631 +3 3868 305 5298 +3 593 4249 6335 +3 6731 6733 5148 +3 3689 3688 3691 +3 1887 308 3262 +3 3262 3693 1887 +3 3639 3638 4335 +3 4249 593 821 +3 3697 1346 2234 +3 3703 3700 326 +3 3126 1110 2307 +3 2462 777 3708 +3 7523 191 5978 +3 2291 310 2289 +3 2289 3095 3712 +3 595 4254 446 +3 1114 313 2932 +3 3712 3095 175 +3 177 6725 4624 +3 6336 3742 1551 +3 175 3715 3712 +3 4988 7445 6718 +3 4254 595 449 +3 3296 3295 3717 +3 620 1996 5800 +3 4030 3154 5065 +3 843 845 3725 +3 3723 60 242 +3 3726 617 4446 +3 1996 620 855 +3 621 5229 4738 +3 1566 320 3733 +3 5229 621 1169 +3 3733 320 2136 +3 329 632 3735 +3 3734 3733 3735 +3 3372 340 5156 +3 64 1378 3780 +3 3548 348 3738 +3 2692 1377 3738 +3 1549 6714 3117 +3 1123 1050 3744 +3 3744 1050 5747 +3 3744 4256 1123 +3 3622 3093 3748 +3 1645 860 6802 +3 5275 6712 2926 +3 860 3222 7179 +3 3464 3461 3756 +3 880 602 3757 +3 4867 7356 6710 +3 1372 116 1670 +3 3758 3377 6926 +3 770 6292 417 +3 3269 3120 3768 +3 3768 5021 2983 +3 6705 6550 4995 +3 3658 3657 3770 +3 2141 5978 191 +3 1702 2609 7082 +3 3778 1349 1202 +3 2262 64 3780 +3 2682 1348 2725 +3 3785 3783 3786 +3 509 2304 3787 +3 509 3787 3788 +3 3787 3094 3788 +3 918 919 3789 +3 3789 3094 3787 +3 3253 2747 1565 +3 4506 1714 546 +3 6696 6698 1072 +3 3760 3027 3791 +3 4311 1361 801 +3 3792 803 1924 +3 3331 323 1530 +3 6214 637 1960 +3 7516 7515 2438 +3 3803 3641 323 +3 775 1963 2393 +3 2982 5056 7522 +3 5035 659 5033 +3 4799 247 6079 +3 932 3804 3806 +3 1216 3808 6790 +3 6693 6694 2367 +3 1540 4301 3232 +3 1217 1218 3808 +3 6137 5387 837 +3 330 40 2306 +3 40 330 2202 +3 1707 7095 6945 +3 3818 3816 3819 +3 6682 6683 5545 +3 5434 6680 7281 +3 3700 3199 3823 +3 2556 331 3824 +3 331 2302 1284 +3 3826 5586 6607 +3 3793 5125 3826 +3 1535 6678 3747 +3 2023 5116 3827 +3 659 3612 5965 +3 6542 6670 6600 +3 2023 2025 5479 +3 6428 7483 6669 +3 3830 3318 22 +3 3831 3017 3835 +3 3415 333 3835 +3 6137 825 5708 +3 336 1038 333 +3 336 2559 1038 +3 2890 837 6136 +3 333 3839 336 +3 5528 3862 2642 +3 1454 1313 6218 +3 306 339 3842 +3 1531 6662 3112 +3 3842 1454 538 +3 1001 7128 2732 +3 3843 2283 5385 +3 3844 7105 3389 +3 340 3845 5792 +3 1170 4844 711 +3 879 342 3851 +3 342 5086 4848 +3 2793 4027 7089 +3 6655 5825 1522 +3 681 1479 6650 +3 3528 3527 3857 +3 1398 344 3857 +3 3857 344 3859 +3 345 3859 346 +3 345 3443 4726 +3 5743 346 3859 +3 346 3442 345 +3 3759 3760 3860 +3 3861 341 3207 +3 4334 349 3863 +3 3866 571 3864 +3 348 3866 2203 +3 6645 6646 6473 +3 3864 349 3866 +3 6163 631 1287 +3 928 1287 3869 +3 1125 65 5755 +3 5772 65 5793 +3 3874 3873 3875 +3 2962 3873 3879 +3 3788 3251 3884 +3 4027 945 2876 +3 2876 7089 4027 +3 2951 3208 3887 +3 2984 2941 3889 +3 2148 2149 3889 +3 853 3090 1660 +3 4964 5779 1138 +3 6638 6639 3301 +3 2322 1525 3894 +3 2461 1909 3894 +3 3897 2516 5304 +3 1235 351 5543 +3 5364 851 3899 +3 3901 3899 3903 +3 302 6634 238 +3 1602 3486 1935 +3 355 3908 1705 +3 6628 6629 7475 +3 1082 5033 5030 +3 3874 357 3909 +3 357 2992 2548 +3 3909 1026 3874 +3 86 4292 3911 +3 2822 1794 3911 +3 4844 1170 7461 +3 5280 701 3912 +3 3917 3605 2636 +3 2287 700 4971 +3 1059 3965 3924 +3 613 3933 2545 +3 360 359 3935 +3 3559 3601 3762 +3 700 1868 1871 +3 6620 6622 385 +3 2619 6618 6550 +3 6613 6614 4034 +3 6613 6611 691 +3 359 360 3936 +3 1950 1457 3937 +3 994 1205 1300 +3 6291 706 4929 +3 3938 1950 6130 +3 818 66 3943 +3 2320 3943 66 +3 818 3198 1554 +3 4705 1603 3663 +3 3943 2320 3 +3 3 2320 1420 +3 4929 706 4452 +3 3944 4444 750 +3 2061 523 3946 +3 3949 3552 1092 +3 2902 6604 2838 +3 3951 2360 4246 +3 2486 4071 3953 +3 4717 2321 2488 +3 2321 4066 2456 +3 6601 6602 739 +3 3849 3848 3955 +3 6597 6598 3514 +3 3352 3335 3959 +3 6607 5586 6297 +3 3960 3959 3961 +3 3963 5030 1094 +3 1062 3965 1093 +3 203 2211 3966 +3 1062 1093 3966 +3 4347 2369 1683 +3 3969 1475 5536 +3 3295 3035 3970 +3 2774 6595 1788 +3 2202 3972 5430 +3 907 3480 7009 +3 3016 3226 3976 +3 1854 2777 1664 +3 5057 6588 6584 +3 3178 3052 1173 +3 6578 6582 1252 +3 2960 367 3978 +3 901 3977 3980 +3 6178 2732 3982 +3 4917 3986 7213 +3 902 368 3987 +3 1678 6576 997 +3 3987 368 4463 +3 432 370 3987 +3 3987 370 2714 +3 374 2509 3992 +3 374 3992 7176 +3 2509 374 2862 +3 4379 2686 2366 +3 1198 4217 370 +3 379 4000 4002 +3 4000 379 2976 +3 382 4002 4792 +3 4002 382 2013 +3 6136 837 5384 +3 2111 4550 754 +3 3795 7243 3637 +3 709 723 991 +3 2585 1115 1026 +3 386 4006 1117 +3 4006 386 3878 +3 1117 3645 386 +3 1468 1471 4008 +3 1709 2295 4014 +3 2972 3804 4015 +3 586 589 4281 +3 4017 586 5199 +3 1494 2747 6760 +3 1024 387 4240 +3 387 1900 4240 +3 5657 2748 6570 +3 294 106 6630 +3 5564 389 4021 +3 3594 6479 2621 +3 4021 2267 3508 +3 389 3004 2267 +3 4022 3004 4 +3 4 5564 6938 +3 2561 1044 4031 +3 3119 390 4039 +3 3006 391 4039 +3 4039 391 3119 +3 6785 1091 6425 +3 4043 4042 4044 +3 3577 3810 4045 +3 751 392 4045 +3 4046 1138 392 +3 3753 3749 4047 +3 2396 1839 4047 +3 5956 393 6481 +3 5403 4057 4620 +3 6063 6923 6568 +3 3326 3877 4062 +3 4062 4058 4063 +3 4012 4008 4065 +3 4065 4064 4069 +3 3708 3710 4070 +3 2552 723 709 +3 2651 394 4073 +3 3994 3049 3486 +3 8 7196 6564 +3 6561 6562 4484 +3 3879 3878 4074 +3 6558 6559 3141 +3 5936 7335 141 +3 5643 3035 155 +3 3088 3089 4084 +3 1580 395 4085 +3 395 5651 4088 +3 3056 3920 4086 +3 4084 4080 4088 +3 4085 4088 4868 +3 5813 1151 3106 +3 723 4238 3050 +3 4091 396 5368 +3 4090 4089 4091 +3 4024 3128 4094 +3 4096 1546 5367 +3 4019 4018 4097 +3 5034 397 4097 +3 4097 397 562 +3 3562 4098 3340 +3 4829 726 4806 +3 2037 398 4099 +3 398 4657 1628 +3 4094 4095 4101 +3 3379 3430 4103 +3 170 2232 4108 +3 4108 1706 170 +3 3734 3347 4111 +3 4838 4197 3452 +3 4110 4109 4111 +3 400 4113 595 +3 400 383 6046 +3 3105 3449 4114 +3 400 446 4114 +3 3337 3338 402 +3 3401 2332 403 +3 3401 4096 2332 +3 4806 726 1733 +3 402 4115 403 +3 403 2332 402 +3 727 4788 5932 +3 4995 1545 6705 +3 1346 5253 4005 +3 261 4120 260 +3 2926 6712 6547 +3 5207 416 4121 +3 4121 4120 4122 +3 727 5286 3599 +3 4123 405 4759 +3 3128 3731 4125 +3 3925 3927 4128 +3 3855 3673 4130 +3 3537 3556 4131 +3 4132 3271 3364 +3 3483 3482 4133 +3 1640 6967 4134 +3 6287 6305 6265 +3 3944 2336 523 +3 6541 6543 6490 +3 734 4892 7426 +3 407 1401 4138 +3 406 4139 2336 +3 4139 406 566 +3 1401 407 4139 +3 4139 407 523 +3 4892 734 1590 +3 166 467 2167 +3 2947 3157 4626 +3 4123 4148 1162 +3 2576 1345 4149 +3 4498 4853 1327 +3 410 6742 193 +3 562 2340 680 +3 6267 7230 6537 +3 2383 411 6179 +3 6179 411 2655 +3 6091 412 6179 +3 6179 412 2383 +3 6534 6535 1107 +3 1476 6532 3362 +3 6998 7307 6530 +3 3453 1712 7040 +3 4154 566 2339 +3 2748 1077 6770 +3 2343 413 2342 +3 747 4769 1367 +3 4502 3603 545 +3 2652 545 3322 +3 1584 2344 4165 +3 2344 3719 4165 +3 3564 3820 4166 +3 6527 4665 1155 +3 3011 416 4167 +3 6519 6522 6021 +3 4167 4166 4168 +3 852 458 4171 +3 4769 747 3084 +3 758 4638 4718 +3 4171 458 3421 +3 4173 4172 4174 +3 6136 2858 2890 +3 7248 418 4181 +3 4181 418 3672 +3 420 2090 4185 +3 420 2419 933 +3 4638 758 4890 +3 6196 791 4591 +3 2419 420 4185 +3 4185 6 2419 +3 1315 4187 3007 +3 1315 2505 4187 +3 4758 424 4190 +3 1474 6515 6674 +3 4190 424 2198 +3 4192 4190 4193 +3 2395 1621 4195 +3 3270 4115 4203 +3 4770 1765 6512 +3 4206 4203 841 +3 540 1824 4207 +3 791 6750 1564 +3 2960 2354 429 +3 429 427 2960 +3 428 5693 3445 +3 428 2354 4208 +3 4213 790 5138 +3 2567 749 4510 +3 430 433 431 +3 2356 430 868 +3 5145 797 5967 +3 431 4164 3061 +3 4215 433 4738 +3 797 3344 2339 +3 370 432 1198 +3 798 4570 3906 +3 3772 4218 4399 +3 1748 3284 1802 +3 6508 6509 7394 +3 4078 155 4219 +3 4219 4218 4221 +3 3534 437 4223 +3 4223 437 558 +3 1748 1802 2853 +3 2830 1824 4227 +3 4226 4224 4227 +3 3487 3343 4231 +3 4570 798 4572 +3 3356 3753 4230 +3 4229 4231 6677 +3 3013 4895 1690 +3 4236 4019 1055 +3 2717 73 2072 +3 6266 2639 2770 +3 1962 1194 7266 +3 1900 1213 4240 +3 2974 3484 3201 +3 3975 3976 4242 +3 1987 4028 1834 +3 1091 6783 6079 +3 440 4243 2357 +3 1461 2716 5191 +3 440 4241 2298 +3 1173 3977 3178 +3 2298 4243 440 +3 7506 4245 23 +3 2176 4249 4248 +3 3728 445 5538 +3 3165 801 1361 +3 5538 3714 3728 +3 3298 4032 4252 +3 5437 602 1002 +3 7186 1002 4253 +3 4254 5 3008 +3 3701 449 595 +3 801 4313 815 +3 4255 4256 952 +3 3744 952 4256 +3 4255 449 4256 +3 3227 3163 4258 +3 1892 1893 4262 +3 2934 3474 4264 +3 915 2191 5680 +3 2413 2294 5760 +3 4266 4265 4268 +3 6491 6492 264 +3 915 808 4763 +3 6486 6488 4338 +3 385 6056 6484 +3 824 1818 6335 +3 6383 456 452 +3 4273 6069 852 +3 4171 4273 852 +3 6867 1609 4273 +3 1626 6869 7299 +3 7299 70 1626 +3 6375 3026 4276 +3 7496 2073 6483 +3 459 4277 6252 +3 459 6341 230 +3 5973 2757 1215 +3 3385 1215 4278 +3 1813 460 4280 +3 4249 821 4248 +3 4289 1595 1601 +3 273 6476 6480 +3 6247 849 4104 +3 821 3888 6370 +3 4152 4153 4293 +3 3190 3272 4295 +3 6798 6474 2313 +3 4308 4177 6887 +3 4307 4284 4177 +3 4311 815 2632 +3 592 3061 1818 +3 2686 461 2366 +3 461 462 2366 +3 6467 6468 311 +3 4317 2763 3494 +3 1597 2154 3853 +3 2154 1597 3802 +3 1447 6465 3865 +3 6660 5199 620 +3 5040 1642 3954 +3 2176 4247 592 +3 239 3432 240 +3 3433 2238 4323 +3 6456 871 1242 +3 2819 1785 4323 +3 4104 849 4961 +3 912 4162 4247 +3 2969 4063 4332 +3 4158 4013 4336 +3 6451 6452 3752 +3 2236 3384 7511 +3 822 1451 4337 +3 876 6406 325 +3 6872 1052 5574 +3 2371 2368 4347 +3 2167 467 4356 +3 3293 4356 3155 +3 1224 4356 3293 +3 472 4357 470 +3 6448 1917 2184 +3 3977 1173 3980 +3 719 473 4358 +3 4358 473 5354 +3 3268 4361 7173 +3 6006 769 2700 +3 2375 1163 4363 +3 3502 3786 4366 +3 1335 1984 4451 +3 1363 3832 1642 +3 4366 596 1945 +3 475 3248 261 +3 4367 891 6656 +3 828 4230 529 +3 6406 876 2894 +3 4230 828 3356 +3 3371 3369 4371 +3 4206 829 4203 +3 4371 1145 3371 +3 2005 478 4372 +3 4372 478 1097 +3 21 2633 5988 +3 1431 1433 1432 +3 4203 829 3270 +3 2984 5248 490 +3 297 841 4200 +3 490 3099 482 +3 491 4373 2376 +3 6439 6440 2381 +3 841 4203 4445 +3 4377 923 491 +3 2707 6941 4906 +3 74 4378 2378 +3 4378 74 7417 +3 458 852 4170 +3 5498 409 2586 +3 5747 5498 5749 +3 3905 2994 4379 +3 3481 3480 907 +3 852 6848 6845 +3 1557 2397 1410 +3 247 3980 6425 +3 647 266 4384 +3 4384 266 2382 +3 4893 496 4384 +3 4384 496 647 +3 5704 1288 4385 +3 1660 497 4385 +3 4385 497 2382 +3 4386 2297 4699 +3 3942 3941 4387 +3 1573 75 2383 +3 503 5502 387 +3 4295 4293 4391 +3 4391 503 4392 +3 4392 503 1024 +3 3278 3485 4395 +3 1425 2706 7290 +3 4395 4394 4397 +3 504 5875 1578 +3 5875 504 3615 +3 3047 4486 4399 +3 2691 4908 4402 +3 4402 3303 2691 +3 4407 4405 4408 +3 3414 3530 4409 +3 4479 505 4412 +3 4412 505 5071 +3 506 535 2384 +3 535 506 216 +3 836 2385 4669 +3 6430 6431 7204 +3 6296 915 4589 +3 939 2477 836 +3 4589 959 6296 +3 1314 2950 4417 +3 2304 2169 4423 +3 909 855 3775 +3 3775 855 5199 +3 4423 512 514 +3 512 4420 514 +3 514 510 4423 +3 514 1404 510 +3 658 517 4429 +3 3233 4430 517 +3 5944 4430 3233 +3 3591 4433 2184 +3 517 4433 3233 +3 4235 4236 4436 +3 1291 518 4436 +3 6421 6422 3403 +3 4436 518 2708 +3 519 4437 520 +3 519 282 2387 +3 1291 520 4437 +3 520 3948 519 +3 2061 522 4442 +3 4442 522 1429 +3 3944 523 2061 +3 868 4162 2356 +3 4403 525 4444 +3 4444 525 2272 +3 4328 7308 6412 +3 3041 7331 6410 +3 3024 1039 334 +3 3995 4405 4448 +3 3062 546 4450 +3 868 4247 4162 +3 543 7494 3624 +3 4453 4452 4454 +3 1039 4244 1079 +3 1087 2496 1802 +3 6005 2512 4432 +3 4456 528 7201 +3 3037 3410 1103 +3 4417 2907 641 +3 4097 877 4019 +3 632 329 4465 +3 877 1042 1055 +3 6879 3664 2212 +3 3872 3871 4466 +3 5454 887 3989 +3 863 5068 4688 +3 6643 1650 3964 +3 531 3246 2391 +3 533 531 2391 +3 533 4466 534 +3 534 531 533 +3 534 3526 531 +3 3315 4174 4473 +3 4472 4471 4473 +3 3655 2961 4477 +3 4412 535 4479 +3 2264 4480 1051 +3 1183 1184 4482 +3 887 2214 895 +3 96 3297 6729 +3 4961 1083 3532 +3 895 3989 887 +3 895 4095 5878 +3 50 6506 6402 +3 4490 1608 2025 +3 6747 577 2022 +3 540 4207 4492 +3 7347 5491 7495 +3 4492 543 540 +3 901 3978 6191 +3 4493 1921 7494 +3 4493 543 4492 +3 3010 3698 4495 +3 139 4503 1462 +3 2196 1522 4503 +3 2174 6408 4504 +3 3770 3769 4507 +3 4507 4506 4509 +3 194 2166 4513 +3 1047 5615 3108 +3 4516 1814 7300 +3 1814 5309 2827 +3 4245 441 4519 +3 4519 441 2398 +3 4519 548 4245 +3 973 549 4521 +3 4521 549 7214 +3 4523 5584 551 +3 2273 5584 4526 +3 2397 1557 2919 +3 137 552 3648 +3 6892 1664 7034 +3 3978 901 6687 +3 5148 6733 6398 +3 4529 1973 6892 +3 1668 554 2400 +3 2400 4530 1668 +3 555 554 5831 +3 554 555 3465 +3 3247 1996 855 +3 5831 3401 555 +3 4535 2544 7211 +3 2386 5694 5697 +3 676 558 2188 +3 3945 561 2188 +3 1400 6395 2654 +3 4537 560 561 +3 397 4538 2340 +3 4539 563 3555 +3 3665 4577 4540 +3 1860 1393 6392 +3 3048 3824 1284 +3 3247 909 5450 +3 6113 6981 3048 +3 406 4543 2339 +3 3955 3957 4544 +3 2695 2381 6384 +3 4555 567 4547 +3 4943 2497 5101 +3 4291 4290 4556 +3 3353 3799 4558 +3 3101 3100 4561 +3 2364 570 4561 +3 4561 570 572 +3 3864 571 4563 +3 2317 4563 570 +3 4563 572 570 +3 570 4564 2317 +3 3906 3905 798 +3 2460 774 4571 +3 3257 2531 4572 +3 4571 4570 4572 +3 4162 912 4828 +3 966 3151 4574 +3 2338 6382 5219 +3 912 4827 4826 +3 966 967 4575 +3 498 1077 4582 +3 2930 3758 4587 +3 7217 4026 4587 +3 7386 1410 3560 +3 294 6630 2117 +3 1380 6380 5877 +3 6376 6377 1406 +3 3109 6750 791 +3 3045 575 4592 +3 384 1820 372 +3 575 3286 2403 +3 4592 6546 1164 +3 4044 913 3823 +3 1081 6546 4592 +3 4597 4596 4598 +3 6366 6367 1758 +3 4600 5005 4603 +3 678 6359 7228 +3 5904 6563 6356 +3 6914 1590 1599 +3 2022 577 4604 +3 4606 583 3454 +3 581 3769 2404 +3 582 4606 2404 +3 4606 582 4604 +3 4604 583 4606 +3 3454 581 4606 +3 3823 913 3700 +3 586 4017 4609 +3 4609 589 586 +3 4608 587 4609 +3 2496 6844 2853 +3 587 4607 589 +3 589 4609 587 +3 3330 3418 4611 +3 4462 4546 4612 +3 4611 4610 4612 +3 1376 6351 5034 +3 1257 590 980 +3 980 4613 1257 +3 5381 4615 590 +3 1822 6345 3409 +3 5381 1841 7354 +3 1071 2864 4618 +3 2837 7061 4347 +3 3458 3457 4621 +3 5615 1047 5828 +3 932 3805 1176 +3 712 4532 2689 +3 4623 4369 4622 +3 4622 4621 4623 +3 1945 4628 475 +3 3913 7404 7224 +3 3805 932 2641 +3 1374 6342 1372 +3 4627 598 6386 +3 1945 475 4366 +3 2759 7058 4396 +3 598 2408 4628 +3 597 4629 2407 +3 7013 6257 4076 +3 597 4122 2408 +3 2408 598 4629 +3 4629 598 4627 +3 2407 3564 597 +3 3089 3177 4631 +3 803 2470 3868 +3 4637 599 278 +3 1148 2409 4818 +3 6332 6334 3182 +3 4818 650 1148 +3 1370 2686 2994 +3 4480 4479 4640 +3 2685 2 2152 +3 4796 600 4640 +3 4640 600 601 +3 601 600 4641 +3 6322 6323 2632 +3 3291 3279 4641 +3 6321 5178 2334 +3 6927 6318 740 +3 6314 6316 6333 +3 4641 1548 601 +3 3127 3156 4642 +3 6313 6312 3681 +3 1002 602 4647 +3 632 604 4653 +3 4653 604 487 +3 4474 3347 4655 +3 4608 605 4661 +3 605 3638 2410 +3 1353 6304 3951 +3 5758 949 3459 +3 6295 6298 5911 +3 4661 720 4608 +3 3229 606 303 +3 303 4662 3229 +3 4599 2619 7464 +3 4662 720 4694 +3 4307 607 4663 +3 6250 3996 3345 +3 731 608 4663 +3 4663 608 7177 +3 949 3803 323 +3 3168 3153 4664 +3 4664 731 4663 +3 3973 3972 4666 +3 414 6291 4927 +3 6286 6288 4554 +3 448 6283 3704 +3 5748 609 4667 +3 4667 609 2411 +3 298 611 4667 +3 4667 611 5748 +3 5987 1674 4671 +3 7376 1313 4675 +3 3165 958 3210 +3 3583 613 4677 +3 5211 3135 6350 +3 3210 958 4849 +3 1936 4678 7370 +3 4678 4677 4679 +3 1410 2397 5893 +3 2681 4532 712 +3 31 5600 4681 +3 4110 3674 4684 +3 7190 618 4684 +3 618 2294 2413 +3 4686 617 2294 +3 617 3726 2235 +3 1723 3220 5289 +3 4697 3012 5533 +3 3760 3759 358 +3 5555 7369 6272 +3 3760 988 3027 +3 3229 4689 619 +3 625 619 4689 +3 991 6890 709 +3 379 4692 2165 +3 625 624 4692 +3 4692 624 4428 +3 2440 716 624 +3 624 625 4689 +3 1718 2181 5244 +3 4695 937 1166 +3 4696 4695 4698 +3 3220 1723 5042 +3 4695 630 4698 +3 4698 630 1370 +3 1287 631 4699 +3 2001 7392 4699 +3 4815 1471 6507 +3 1337 6263 1195 +3 604 632 4465 +3 252 7453 2675 +3 604 4465 2390 +3 4408 3046 4706 +3 4706 4700 4707 +3 4034 6614 6259 +3 4710 1175 4033 +3 1175 6012 4712 +3 3653 3652 4715 +3 3431 3430 4716 +3 4718 4639 758 +3 4511 636 4719 +3 636 6671 1669 +3 6175 994 4942 +3 4942 994 4941 +3 1968 2046 3616 +3 6130 640 4721 +3 4721 640 1951 +3 6248 6249 7117 +3 2787 3323 4432 +3 2110 4724 1491 +3 4724 2110 641 +3 4418 4417 641 +3 6243 6244 6948 +3 1586 5535 1741 +3 641 2110 4725 +3 2046 997 3616 +3 645 725 4049 +3 5461 6357 6237 +3 725 645 4896 +3 262 7077 199 +3 3575 3404 725 +3 997 4487 677 +3 649 4734 3205 +3 4734 649 1318 +3 4735 3036 493 +3 1067 653 4737 +3 4737 653 655 +3 654 655 653 +3 655 654 1952 +3 1074 1591 6996 +3 6226 6227 3494 +3 653 4741 654 +3 3798 3311 4744 +3 1319 6224 5503 +3 5545 1004 3614 +3 4747 89 5120 +3 6217 6218 1313 +3 3471 4747 49 +3 4747 4752 89 +3 4748 2348 2423 +3 5876 2451 6860 +3 5160 2327 920 +3 2451 5876 1915 +3 623 4325 6893 +3 6212 6213 2124 +3 1004 6271 5129 +3 1267 661 6812 +3 6812 661 3583 +3 4769 3084 1196 +3 6763 6004 5991 +3 2721 663 4771 +3 4771 663 2334 +3 4501 1074 6996 +3 6093 5281 3314 +3 1591 1074 5952 +3 668 673 4773 +3 1869 1423 4346 +3 4773 673 63 +3 1079 3441 334 +3 673 668 2425 +3 4745 4744 4776 +3 1012 4955 4467 +3 956 4779 3558 +3 4263 3513 4781 +3 4957 1012 2611 +3 6378 1025 3588 +3 2209 680 4783 +3 4783 680 2340 +3 4926 1458 332 +3 6491 3567 4785 +3 3227 3512 4790 +3 4558 4556 4791 +3 4002 4000 4792 +3 684 683 4792 +3 2426 6991 1644 +3 682 683 684 +3 2662 926 1874 +3 682 4500 2426 +3 3588 1025 1969 +3 1303 6207 5879 +3 1034 5037 4928 +3 684 3225 682 +3 7176 686 374 +3 4198 4257 4798 +3 687 1029 2007 +3 1009 7030 6205 +3 6201 6202 2985 +3 7136 7130 7279 +3 1192 4800 1029 +3 688 4801 689 +3 688 3949 2430 +3 5037 1034 3124 +3 689 3948 520 +3 4381 3380 136 +3 690 4704 2841 +3 5070 4805 2733 +3 1296 6198 6735 +3 4805 5070 4679 +3 4810 1228 1812 +3 6735 6198 6194 +3 1228 817 4813 +3 6187 6188 1017 +3 3028 335 693 +3 692 4815 693 +3 5940 5942 6833 +3 1064 6184 2805 +3 692 3477 778 +3 693 4815 3028 +3 425 7324 2428 +3 693 3162 692 +3 6787 6180 1792 +3 5055 698 4816 +3 4816 698 5266 +3 2468 1037 291 +3 7387 3560 2684 +3 1770 650 4818 +3 3731 4054 4823 +3 1934 694 3218 +3 2216 1697 3912 +3 3912 701 2726 +3 4087 3441 3586 +3 4826 4828 912 +3 1042 3552 573 +3 2098 5110 4806 +3 1864 3150 3122 +3 2432 4829 705 +3 2049 5559 7426 +3 3552 1042 1092 +3 3552 7374 573 +3 1538 3670 4832 +3 4835 4313 801 +3 1538 165 4835 +3 6175 2708 518 +3 1391 1162 164 +3 4839 7349 376 +3 3568 4839 376 +3 4839 3568 4836 +3 4376 7088 5943 +3 3357 4290 4842 +3 883 710 4842 +3 1011 1014 1943 +3 1682 710 5194 +3 883 1451 4843 +3 711 3936 360 +3 3751 711 4844 +3 4846 4457 537 +3 4846 4845 4847 +3 1307 4848 5086 +3 715 4849 958 +3 4849 3391 2868 +3 5908 1615 4851 +3 4851 2437 5147 +3 4358 716 4856 +3 5257 719 4856 +3 4856 719 4358 +3 4858 720 4661 +3 721 4858 2410 +3 4858 721 931 +3 3861 3860 4860 +3 4304 4497 4862 +3 4862 4860 4863 +3 78 4083 3365 +3 1055 4019 877 +3 2693 6169 5704 +3 3262 5674 4864 +3 7522 5056 5515 +3 2442 4864 78 +3 1061 3541 3539 +3 4362 4361 5702 +3 5847 806 2077 +3 1061 1508 5622 +3 1082 5030 3963 +3 7051 1168 4873 +3 2181 1718 6235 +3 6161 6163 928 +3 4874 17 6094 +3 5459 1086 3428 +3 4471 4024 4877 +3 3311 3040 4878 +3 4102 4779 4879 +3 4878 4877 4879 +3 3044 1089 5464 +3 729 2813 730 +3 729 730 2899 +3 730 732 2899 +3 3428 1086 3113 +3 1092 3423 3949 +3 1089 3503 6583 +3 4872 735 4888 +3 735 3175 2448 +3 738 737 4888 +3 4888 737 4872 +3 4889 738 1336 +3 1739 144 6246 +3 4890 738 4888 +3 4384 497 4893 +3 3126 2307 5276 +3 741 2450 742 +3 742 1888 741 +3 1888 742 743 +3 743 2278 3597 +3 80 6860 2451 +3 5178 80 4897 +3 1367 124 4771 +3 6154 6155 7199 +3 80 742 4897 +3 4235 4394 4900 +3 3492 4018 4901 +3 4901 4900 4902 +3 4265 4903 5102 +3 6360 7244 6153 +3 6735 6194 6149 +3 4905 2235 2160 +3 3423 1092 1562 +3 4904 4903 4905 +3 1103 3410 3408 +3 1103 4458 3037 +3 6266 1236 4908 +3 1927 1350 2789 +3 13 6183 6145 +3 5987 2051 4910 +3 7041 1105 3392 +3 4913 745 4912 +3 6140 6141 786 +3 4912 745 763 +3 4913 4912 2452 +3 837 825 6137 +3 1167 2174 5861 +3 2490 177 242 +3 2174 1167 5508 +3 6131 6133 556 +3 4925 753 4923 +3 4923 753 4389 +3 3392 1105 5495 +3 6125 6126 6687 +3 754 4925 2111 +3 4923 755 5126 +3 2578 2663 2249 +3 3851 4848 4927 +3 5480 1574 2701 +3 4452 3598 4929 +3 2929 2161 4930 +3 2699 757 5328 +3 5328 757 4930 +3 6789 7007 1045 +3 6119 6120 2179 +3 3180 511 2006 +3 760 759 4933 +3 4933 2454 4931 +3 83 2453 4934 +3 4936 3097 2433 +3 4891 762 4936 +3 4936 762 766 +3 4912 763 4937 +3 4938 764 4937 +3 764 2452 4912 +3 3398 4938 553 +3 4937 766 762 +3 762 4938 4937 +3 2858 1102 5386 +3 1170 6015 1901 +3 3375 1118 3374 +3 5448 768 767 +3 767 768 2614 +3 3374 1118 5720 +3 3544 3312 4940 +3 5004 4491 6114 +3 4941 4940 4942 +3 1283 6111 3514 +3 2460 4943 5101 +3 1154 6902 2878 +3 6018 6636 2709 +3 6106 6107 5561 +3 5386 1102 1796 +3 3794 2872 6103 +3 4943 2460 3294 +3 6902 1154 6729 +3 5690 776 4946 +3 4946 776 986 +3 777 2462 4948 +3 5136 1278 2956 +3 779 4948 986 +3 4948 779 2367 +3 6401 780 4289 +3 4734 781 4951 +3 4951 781 4732 +3 6098 6099 929 +3 1682 1155 3357 +3 4951 784 4734 +3 7013 4460 4155 +3 4951 780 4952 +3 669 2929 757 +3 4957 1903 1704 +3 4957 4955 1012 +3 3249 3250 4959 +3 2644 785 4959 +3 785 2466 6999 +3 786 6141 6097 +3 1394 5559 217 +3 1246 789 4960 +3 4960 789 5709 +3 2840 6204 6090 +3 916 6087 5176 +3 3272 3961 4963 +3 3367 4152 4965 +3 4963 4962 4965 +3 1106 5179 5177 +3 3773 3777 4966 +3 4969 790 2092 +3 4175 5146 6842 +3 4970 795 3648 +3 1871 4971 700 +3 796 5671 2365 +3 3357 1155 4665 +3 1924 803 7203 +3 3332 3390 1895 +3 506 4973 2222 +3 4044 3823 4975 +3 2959 2444 4274 +3 4977 3941 136 +3 3396 4978 4977 +3 1177 3952 6739 +3 2470 803 3792 +3 4137 1997 3901 +3 3762 2779 6970 +3 5179 1106 3136 +3 805 4980 1413 +3 4980 805 3327 +3 1413 2945 805 +3 3759 3863 4981 +3 4981 1413 6417 +3 1265 6082 5306 +3 3030 5770 305 +3 806 5847 1259 +3 1091 6079 247 +3 4983 4986 3118 +3 4983 233 810 +3 6075 6077 3981 +3 1190 882 6567 +3 810 4986 4983 +3 1247 6071 4743 +3 4986 810 4916 +3 4610 4015 4987 +3 882 1190 2597 +3 5158 6254 1334 +3 811 4989 2498 +3 4989 811 2379 +3 393 813 4989 +3 813 1483 2498 +3 4546 4544 4990 +3 1243 6060 2348 +3 2967 3127 4994 +3 4992 4990 4994 +3 6312 3507 4998 +3 5001 3177 3305 +3 987 814 5001 +3 5001 814 5690 +3 987 1189 5002 +3 4813 817 2922 +3 5006 2479 2637 +3 4270 1196 3084 +3 1196 2946 4769 +3 3984 819 5008 +3 819 87 2481 +3 2481 5008 819 +3 5185 1201 3081 +3 6057 6058 1459 +3 5008 2481 7092 +3 3774 2481 5279 +3 87 5279 2481 +3 820 1070 5009 +3 729 4541 5011 +3 5011 820 5009 +3 5009 6539 5011 +3 3081 1201 6867 +3 2485 6817 160 +3 5917 5012 7476 +3 1300 1205 5183 +3 920 2327 5013 +3 4301 3266 5026 +3 5020 5019 5026 +3 5035 5033 1082 +3 823 4916 5036 +3 823 4584 4766 +3 823 5036 5041 +3 5041 4584 823 +3 4789 3984 5045 +3 499 826 5045 +3 5183 1205 1583 +3 4669 826 5050 +3 4459 1207 3058 +3 6046 6047 4113 +3 5051 827 3339 +3 5051 6462 149 +3 1732 265 1625 +3 3578 1442 5053 +3 1207 3057 352 +3 2187 5054 6533 +3 3206 830 5058 +3 2489 5058 830 +3 5058 832 3206 +3 3359 5062 2035 +3 5063 832 5058 +3 255 2384 4412 +3 4553 1195 5035 +3 5074 834 5341 +3 3283 3239 5075 +3 6782 1209 210 +3 5080 835 5077 +3 5077 5074 5080 +3 5836 5837 5082 +3 4876 4789 5083 +3 5084 2385 34 +3 1195 4342 3264 +3 2560 2432 5088 +3 3173 3495 4985 +3 2412 5233 4187 +3 1238 2138 782 +3 5090 4985 2594 +3 1209 3037 209 +3 6031 7057 7209 +3 5096 4945 4204 +3 1849 842 5096 +3 5096 842 2483 +3 845 843 5097 +3 845 5097 842 +3 6000 846 5155 +3 846 4092 5155 +3 3412 1259 810 +3 848 774 5101 +3 3832 1363 1110 +3 4073 3051 5104 +3 3073 6387 6030 +3 848 2498 5104 +3 2546 1251 3036 +3 2498 848 5105 +3 5105 848 5101 +3 5105 2497 2054 +3 3036 1251 3784 +3 1490 2216 6569 +3 6026 6028 1280 +3 2216 1490 3709 +3 1234 6023 5094 +3 5107 3836 5108 +3 2012 5843 888 +3 1259 5036 4916 +3 5109 2012 1532 +3 3752 6452 6014 +3 3574 850 5111 +3 850 3575 2499 +3 3152 125 1797 +3 5111 854 3574 +3 528 851 5112 +3 5112 854 2096 +3 2499 853 3054 +3 3054 5114 2499 +3 5114 854 5111 +3 3069 3053 5118 +3 2755 857 5119 +3 2933 1269 1944 +3 1227 2637 2479 +3 5120 5123 2190 +3 5120 857 5123 +3 1437 1285 3615 +3 859 2672 6242 +3 859 6459 5126 +3 6001 6002 1329 +3 858 5127 1324 +3 5127 858 2111 +3 5127 2111 6459 +3 3615 1285 1467 +3 5127 859 6242 +3 3655 1295 2961 +3 5233 2412 2487 +3 3429 6264 5130 +3 861 5131 1188 +3 5131 861 3468 +3 1188 3022 861 +3 865 862 5132 +3 5132 862 5128 +3 1295 2927 3076 +3 4421 1314 1321 +3 862 865 3073 +3 5133 4618 4322 +3 1072 867 5133 +3 5133 867 5132 +3 6976 5950 7484 +3 3495 3498 2860 +3 873 5151 6492 +3 1321 2953 4421 +3 3665 5155 4559 +3 3665 873 5155 +3 5164 5163 5167 +3 2108 1316 2910 +3 3523 2928 5169 +3 2370 874 5169 +3 5169 874 1122 +3 4549 6234 5993 +3 1316 2225 3327 +3 2346 3280 3505 +3 1222 6391 6019 +3 875 4647 1122 +3 5746 4652 5170 +3 4652 875 5170 +3 1318 2693 4734 +3 878 5172 621 +3 5172 878 4811 +3 4586 4585 5173 +3 5174 5173 5175 +3 3136 2928 5179 +3 5118 5117 5182 +3 1300 5183 786 +3 3173 4043 5184 +3 4845 322 5186 +3 2016 5189 4036 +3 196 7469 7399 +3 1125 4036 5190 +3 2208 879 161 +3 710 883 4843 +3 4843 5194 710 +3 2011 885 1717 +3 5196 885 2011 +3 2501 4353 5196 +3 1485 6559 2652 +3 4709 1233 1907 +3 4362 2502 5202 +3 2502 1801 2587 +3 5237 485 5067 +3 5208 5836 5082 +3 2693 1318 1289 +3 1157 888 5209 +3 888 6656 5210 +3 4920 5015 7377 +3 1627 4051 7521 +3 4286 892 5212 +3 892 3694 2503 +3 5212 2503 5213 +3 3077 1526 6573 +3 5212 90 4286 +3 2503 2198 5213 +3 1199 2198 19 +3 4448 4944 5217 +3 2463 894 5218 +3 5223 893 5220 +3 5220 893 6113 +3 6574 2641 975 +3 5220 894 5223 +3 4969 4968 5224 +3 6554 804 3718 +3 3718 5225 6554 +3 5025 4968 5481 +3 7364 6437 7427 +3 793 1360 5983 +3 5227 5226 5228 +3 2891 7019 1699 +3 5020 4215 5230 +3 5232 897 7325 +3 2412 6758 7043 +3 5233 897 4187 +3 899 3378 135 +3 3378 899 3506 +3 4530 5981 5980 +3 7019 3445 1699 +3 1326 5360 5958 +3 1300 4941 994 +3 3316 900 941 +3 7395 1328 5369 +3 900 3316 1383 +3 5369 1328 6022 +3 4102 4101 5239 +3 368 902 704 +3 5241 3589 2215 +3 906 1681 4463 +3 5970 5971 5584 +3 5240 5239 5241 +3 1343 5384 6390 +3 5245 907 1716 +3 2229 5968 1902 +3 1343 1796 1102 +3 2508 2938 5462 +3 5625 1365 5391 +3 5391 1365 1974 +3 1371 5648 502 +3 4949 275 812 +3 914 910 4281 +3 5648 1371 4777 +3 910 4348 5450 +3 2689 4532 4708 +3 1206 929 6099 +3 3312 1422 5407 +3 1422 5406 6137 +3 2508 4302 914 +3 4941 1300 4344 +3 5250 4518 3304 +3 5250 917 4518 +3 1204 5963 488 +3 919 918 5251 +3 5251 918 3992 +3 2509 2606 5251 +3 2606 2509 5353 +3 1203 5958 3569 +3 1724 920 5013 +3 2468 4967 4381 +3 1010 1426 5456 +3 5456 1426 5454 +3 5255 926 1226 +3 927 5256 7509 +3 927 3268 2513 +3 7509 5256 5258 +3 931 721 5257 +3 5257 4856 931 +3 5257 935 5092 +3 5258 933 2113 +3 5258 935 7509 +3 7276 1428 5458 +3 936 3569 2529 +3 5262 1179 5921 +3 2759 941 3765 +3 4132 4919 5273 +3 5458 1428 2268 +3 4028 1919 942 +3 1919 4306 942 +3 1668 3360 5277 +3 663 6516 1473 +3 1105 5540 539 +3 4833 946 5282 +3 5283 5284 3867 +3 5283 946 5284 +3 3599 4788 727 +3 7386 3148 2740 +3 5474 380 2186 +3 1435 5497 5496 +3 1501 5609 5776 +3 4328 6412 5954 +3 1039 2740 3148 +3 4841 6311 1132 +3 948 5832 1136 +3 3800 3190 5291 +3 5292 5291 5293 +3 4675 4676 5295 +3 4233 4809 5297 +3 5299 5297 5300 +3 5301 985 7138 +3 1437 3615 504 +3 5740 1453 2292 +3 460 5303 2417 +3 979 951 5304 +3 6004 4220 603 +3 7151 804 6554 +3 351 951 1695 +3 979 953 5306 +3 7402 1760 1212 +3 2292 1453 1481 +3 5306 953 6615 +3 1968 5308 3805 +3 569 954 5319 +3 515 5941 463 +3 7402 2778 1760 +3 5319 954 2088 +3 3531 3475 5310 +3 5874 961 5310 +3 1453 1114 2932 +3 5313 957 3358 +3 1481 146 2281 +3 5313 3053 957 +3 3188 4847 5315 +3 2146 3557 2347 +3 1191 5933 6065 +3 2146 569 5319 +3 5313 961 5321 +3 7355 962 5322 +3 962 2918 3743 +3 1187 5931 2297 +3 2848 964 5323 +3 5323 964 1842 +3 5324 565 4449 +3 5494 5532 2523 +3 3892 3358 5326 +3 5328 965 5329 +3 5329 965 5326 +3 5329 5326 4496 +3 2977 3657 5332 +3 3928 1223 5332 +3 967 966 5333 +3 1482 2558 2127 +3 5333 966 4574 +3 6001 967 5333 +3 5334 1273 7269 +3 5185 5184 5337 +3 1307 4849 715 +3 3491 3490 5339 +3 4975 4973 5340 +3 5339 5337 5340 +3 4477 968 5345 +3 1482 1896 1036 +3 5345 969 4477 +3 3917 3915 5347 +3 969 1364 5347 +3 1185 2614 768 +3 4138 3169 5348 +3 5348 3169 1364 +3 5348 969 5345 +3 3259 3260 5349 +3 5350 1388 4298 +3 5351 4243 2298 +3 4833 6769 1178 +3 971 5354 473 +3 5354 971 5351 +3 1392 5266 5355 +3 549 973 2253 +3 3806 4775 5359 +3 1993 2981 4814 +3 5261 974 5361 +3 974 5260 2529 +3 4803 1484 2065 +3 5361 5360 1326 +3 975 5359 977 +3 977 5361 975 +3 5361 977 5261 +3 4865 3645 5363 +3 4893 2593 5365 +3 5365 5363 5366 +3 4967 2468 1985 +3 1432 5915 2416 +3 1272 6558 5372 +3 1272 929 5373 +3 5374 1099 3445 +3 2285 5149 6846 +3 4849 1307 3391 +3 3579 3580 5377 +3 1901 6015 3579 +3 4005 4119 1346 +3 5912 5913 4581 +3 3580 3392 5378 +3 3692 1321 4418 +3 5908 628 3722 +3 1410 7386 1557 +3 953 979 5304 +3 953 5304 2516 +3 4615 980 590 +3 1493 2105 4595 +3 1354 982 6307 +3 435 2798 1384 +3 3901 1997 2163 +3 5901 5902 799 +3 4064 3477 5382 +3 7200 474 3647 +3 5622 3541 1061 +3 4238 3856 5386 +3 3166 5192 5390 +3 2766 1357 1511 +3 2613 2764 5017 +3 527 1508 5626 +3 1974 1975 5391 +3 5394 1974 6799 +3 6019 1019 1222 +3 986 776 779 +3 776 5395 779 +3 814 987 5002 +3 814 5002 2475 +3 5398 5395 5399 +3 5625 3342 4228 +3 5400 1552 989 +3 5896 5897 3215 +3 5494 5856 5873 +3 989 1552 1211 +3 736 4182 7148 +3 5400 989 2581 +3 1510 5622 527 +3 990 984 4305 +3 990 4388 2535 +3 5889 5890 6469 +3 3517 3285 1576 +3 6133 1514 5635 +3 5635 1514 5634 +3 5886 5860 6661 +3 1516 5091 4866 +3 1275 6729 2885 +3 3629 3615 1467 +3 3614 3187 5402 +3 5091 1516 2316 +3 4500 4499 5404 +3 2954 3957 5405 +3 3278 3312 5407 +3 2538 6553 2305 +3 3368 4291 5410 +3 5873 5803 5494 +3 3799 3798 5411 +3 835 992 5413 +3 5413 992 5066 +3 3960 3800 5415 +3 5268 3493 5417 +3 5871 1174 6247 +3 5416 5415 5417 +3 5419 4795 5420 +3 4795 5419 5422 +3 2911 2119 5423 +3 1532 1157 2323 +3 4659 4658 5435 +3 2736 5868 3903 +3 4619 3886 5428 +3 6394 6273 3162 +3 4051 513 3297 +3 5429 6567 635 +3 4140 6771 5999 +3 2070 3703 1512 +3 996 4715 2541 +3 1157 1532 2012 +3 1126 4716 996 +3 2542 1539 1987 +3 662 1539 7497 +3 5864 5866 1537 +3 4418 1321 1314 +3 5949 1000 6262 +3 1000 1236 6262 +3 18 669 1685 +3 4499 3016 5438 +3 2967 2954 5439 +3 1795 1003 5441 +3 2752 5854 35 +3 5441 1003 1032 +3 7429 1550 5789 +3 1550 7057 7033 +3 3828 3023 5445 +3 5444 5441 5445 +3 5446 5263 2257 +3 7521 4051 96 +3 5734 1005 5446 +3 5446 1005 1008 +3 3029 2606 3325 +3 5447 5448 6843 +3 6247 4670 5871 +3 5873 2210 5803 +3 1006 5153 2081 +3 767 1007 2459 +3 2459 5448 767 +3 5447 1008 1005 +3 1005 5448 5447 +3 3970 3969 5452 +3 5452 5453 7322 +3 1159 5843 2012 +3 3989 4126 2469 +3 4310 4309 5457 +3 5838 5839 773 +3 2611 4954 4957 +3 5456 5454 5457 +3 1970 3732 5389 +3 5873 2610 2210 +3 3649 1013 218 +3 5828 5830 4484 +3 1553 7420 129 +3 2963 5826 678 +3 3428 3426 218 +3 3067 5460 4033 +3 717 1649 5460 +3 3067 1559 5460 +3 1554 66 818 +3 2273 5463 2275 +3 3703 2070 2206 +3 1089 3044 2895 +3 4141 4140 5465 +3 5465 2895 3044 +3 5187 3592 5468 +3 1015 5470 2615 +3 1015 2089 4690 +3 3131 1016 5471 +3 3219 5822 7333 +3 66 1554 5793 +3 5471 3436 5473 +3 2788 1450 5474 +3 6043 7191 5817 +3 4346 7032 5475 +3 4791 1325 4790 +3 4790 1325 2279 +3 124 1367 4769 +3 1222 1019 5482 +3 5482 3473 3846 +3 1020 5486 1604 +3 5486 1020 1952 +3 1424 5712 1130 +3 1023 1022 5488 +3 2545 3933 5489 +3 5489 1022 5490 +3 1022 1023 5490 +3 5296 5295 5493 +3 5496 5495 1435 +3 387 1024 503 +3 4525 2704 2947 +3 4153 4954 5506 +3 3816 3095 5510 +3 6309 5028 7387 +3 1027 1026 3909 +3 3909 5512 1027 +3 4278 1028 2549 +3 2549 1028 2620 +3 1560 1233 204 +3 2549 5512 4278 +3 5514 1214 3385 +3 5512 2548 5514 +3 3881 5300 5516 +3 3413 2992 5517 +3 4103 4105 5520 +3 1030 5522 2550 +3 1150 2600 1261 +3 5522 1030 5519 +3 5519 1213 5522 +3 5500 7023 180 +3 900 1031 941 +3 3840 1032 1003 +3 1003 5528 3840 +3 3942 3644 5530 +3 6350 2212 5211 +3 5538 5537 256 +3 1233 1560 1907 +3 5304 351 3897 +3 1036 2558 1482 +3 2599 5505 4772 +3 93 2556 5548 +3 1309 1563 1762 +3 1367 2450 747 +3 4172 3828 5550 +3 4054 4472 5551 +3 2312 1040 5554 +3 1040 1242 871 +3 1762 1563 1851 +3 5551 5550 5554 +3 1041 5557 5588 +3 1456 1411 4972 +3 7133 2229 7131 +3 4136 2065 1484 +3 2143 1043 5560 +3 1043 1276 1555 +3 418 3212 1489 +3 2223 1044 2561 +3 6100 2223 1276 +3 5564 1046 5565 +3 4 6938 229 +3 5190 5189 5565 +3 5881 2269 69 +3 2269 5881 541 +3 5433 6052 594 +3 5566 1048 3888 +3 324 5258 5256 +3 3888 3887 2562 +3 1049 1048 5566 +3 1411 4911 1336 +3 4337 3368 5567 +3 85 3002 702 +3 5567 1049 822 +3 5569 1049 5566 +3 5183 1583 5867 +3 5572 898 4205 +3 5867 1583 5866 +3 5574 2512 6872 +3 1053 2787 5574 +3 2787 1053 5575 +3 3692 1402 5577 +3 5142 5141 5578 +3 5439 5438 5581 +3 3522 3285 3517 +3 2856 5807 1778 +3 5801 5802 5948 +3 5580 5579 5581 +3 5582 5141 7262 +3 1587 1632 3818 +3 364 1054 5592 +3 95 5592 2568 +3 5592 5595 2211 +3 5132 867 865 +3 90 2504 5594 +3 5594 1068 1542 +3 95 2565 5595 +3 5059 1057 5595 +3 1057 1062 5650 +3 3160 6839 5798 +3 1632 1587 2135 +3 5596 5598 5679 +3 5596 1062 1057 +3 1057 5598 5596 +3 1063 5573 5601 +3 5573 1063 5603 +3 5603 1063 1843 +3 2572 5205 5272 +3 3169 3882 5605 +3 4519 4768 5157 +3 4481 3460 5608 +3 11 1065 5608 +3 1065 5609 1136 +3 5258 324 933 +3 5609 1066 5776 +3 4658 4907 5611 +3 5614 1542 6698 +3 4232 2700 769 +3 6490 6543 5794 +3 1068 865 867 +3 3872 3102 5616 +3 5618 2163 1997 +3 3940 3108 5618 +3 5303 5302 5621 +3 3541 5622 526 +3 1882 1350 1933 +3 5391 3342 5625 +3 507 527 5626 +3 477 5792 3844 +3 5009 1070 5628 +3 4526 4523 5631 +3 1514 1071 5195 +3 5634 5631 7358 +3 4416 4415 5636 +3 7033 5789 1550 +3 3440 3438 5638 +3 1073 5639 4949 +3 7462 1144 5788 +3 1073 1390 4758 +3 2179 6120 5782 +3 3143 424 1390 +3 6387 185 1390 +3 5778 5779 4964 +3 188 6122 5777 +3 4696 3049 5640 +3 5773 5774 4750 +3 2592 3129 1524 +3 138 1613 4788 +3 1916 5316 7520 +3 4788 1613 5932 +3 2029 2681 6609 +3 4078 5730 5643 +3 1233 4709 7498 +3 5585 7180 7181 +3 1076 536 3035 +3 1411 1456 4906 +3 5645 1075 5644 +3 5644 1075 2230 +3 4600 3300 5645 +3 5644 4777 5645 +3 1129 5768 1763 +3 536 1877 502 +3 4777 5644 5648 +3 6770 1077 5649 +3 3716 1965 2577 +3 2577 5658 3716 +3 4040 1456 6877 +3 6404 4533 4573 +3 1397 2654 6395 +3 1153 1462 4503 +3 1470 7251 1464 +3 4635 1080 5658 +3 5658 1080 1992 +3 1620 6880 7393 +3 5659 1081 5062 +3 6880 1620 1942 +3 2131 1626 1609 +3 5029 1494 5660 +3 5755 5758 3459 +3 1609 1626 70 +3 20 1641 1600 +3 5665 5664 5667 +3 2852 1879 5670 +3 4866 1084 5670 +3 5670 1084 1937 +3 1085 1937 1084 +3 7049 1085 1543 +3 4020 2696 1939 +3 1600 1641 1598 +3 6801 6803 860 +3 1462 3516 139 +3 1939 2696 447 +3 2639 2439 2474 +3 1645 2604 7286 +3 1653 6262 1236 +3 6262 1653 5198 +3 4954 2611 5506 +3 6713 1665 1549 +3 3901 2163 3563 +3 1113 6556 2968 +3 5680 808 915 +3 2945 4564 5685 +3 5682 5681 5685 +3 2968 6461 1113 +3 1096 1094 5400 +3 1237 1096 5686 +3 3437 1097 478 +3 478 5691 3437 +3 1237 1098 5691 +3 5691 1098 884 +3 4274 2389 3509 +3 3754 5697 4210 +3 5753 670 6975 +3 2986 5669 5699 +3 3184 3639 5702 +3 5702 1101 2582 +3 1101 4335 4765 +3 4440 2616 7224 +3 5376 2582 1101 +3 6399 7223 5750 +3 2582 5376 4840 +3 789 5412 5709 +3 3411 5665 5711 +3 5749 5748 611 +3 5714 5713 5716 +3 5676 5717 1018 +3 5862 1109 5718 +3 5743 5745 122 +3 5718 1109 2094 +3 6024 1469 2801 +3 5177 3374 5720 +3 4976 3468 5722 +3 5725 5723 494 +3 4075 4074 5726 +3 3404 3458 5728 +3 4865 4869 5729 +3 5728 5726 5729 +3 1665 3264 6714 +3 5796 2213 5732 +3 1990 6888 7036 +3 5829 6635 5742 +3 1512 3185 2070 +3 3907 3908 5736 +3 4429 5519 5737 +3 2810 1112 1867 +3 1867 5738 2810 +3 3043 5805 5739 +3 4006 1115 5741 +3 6914 4562 289 +3 5740 1116 5741 +3 1116 5739 1117 +3 1869 5938 2514 +3 1117 5741 1116 +3 1116 5740 2292 +3 5741 1117 4006 +3 5177 5742 1106 +3 2492 2782 5044 +3 5044 6150 5371 +3 2536 5371 6150 +3 6707 1670 1545 +3 344 5743 3859 +3 3132 1121 7470 +3 122 5745 2195 +3 5170 1122 874 +3 874 5746 5170 +3 5745 5743 5746 +3 2586 5749 5498 +3 1112 2810 1871 +3 3013 3014 4895 +3 3256 1104 3294 +3 2730 6448 5736 +3 4036 1125 5755 +3 2473 6295 5733 +3 949 5758 1816 +3 1126 996 2541 +3 5759 998 1126 +3 5758 5755 5759 +3 1128 1127 5764 +3 1545 1670 6706 +3 6395 1128 5764 +3 2654 1397 1705 +3 5252 5202 2502 +3 5766 1129 4536 +3 5768 1129 5961 +3 5769 1129 5766 +3 1244 1130 5712 +3 1130 2589 1424 +3 3185 1512 6964 +3 204 7498 5770 +3 5496 1133 5771 +3 5771 1133 5607 +3 1135 5771 6822 +3 5771 1135 5496 +3 5580 3975 5773 +3 3610 5223 5775 +3 5774 5773 5775 +3 1673 6013 6362 +3 1573 1577 5777 +3 392 1138 5779 +3 4537 3005 5780 +3 5779 5778 5780 +3 178 51 248 +3 2957 3538 5786 +3 4371 1141 5788 +3 5140 5788 1141 +3 1144 5786 1145 +3 1145 5788 1144 +3 5788 1145 4371 +3 3020 1146 998 +3 998 5791 3020 +3 5791 1147 477 +3 3844 4947 477 +3 5726 5728 3107 +3 5792 1147 3198 +3 65 66 5793 +3 5793 1147 5791 +3 494 5723 5287 +3 2435 6821 5720 +3 6024 7079 4635 +3 5794 2409 1148 +3 2584 1567 5732 +3 4805 2431 2733 +3 2733 2431 765 +3 4258 4257 5801 +3 4173 3604 5802 +3 6250 3345 6738 +3 3710 3023 5806 +3 5802 5801 5806 +3 6196 4591 1485 +3 1851 7221 7223 +3 6013 1673 6014 +3 1151 1150 5810 +3 2601 1167 5861 +3 4656 3767 3114 +3 2185 2601 5813 +3 5861 1150 5813 +3 1150 1151 5813 +3 6577 1678 314 +3 4643 4642 5817 +3 6574 1678 2046 +3 6534 1679 4270 +3 1153 1522 5825 +3 72 6327 5717 +3 2963 1152 5826 +3 5826 1152 5688 +3 5825 1152 2963 +3 1679 5246 1196 +3 1957 7402 1212 +3 3366 3367 5833 +3 5830 5828 2650 +3 5713 5714 4352 +3 2983 4871 2090 +3 2604 6802 1585 +3 6525 1682 5879 +3 4129 4953 1275 +3 1504 1505 5838 +3 245 1007 773 +3 5254 922 5841 +3 5841 922 6741 +3 5839 5838 5841 +3 3630 1156 5842 +3 3518 6489 5711 +3 1212 7255 7378 +3 5879 3588 6525 +3 888 1157 2012 +3 1163 2375 5845 +3 5843 1159 5845 +3 1159 5842 1163 +3 1163 5845 1159 +3 5251 2606 5846 +3 2606 3029 5846 +3 5263 1164 5849 +3 18 1685 7464 +3 5849 1495 5263 +3 1495 5467 5850 +3 5419 1165 5851 +3 2522 5718 2094 +3 5848 2539 5851 +3 5852 5848 5851 +3 7082 2609 5853 +3 5853 105 2804 +3 5126 755 5855 +3 2523 5856 5494 +3 2163 4260 4098 +3 2269 5057 6584 +3 1819 5043 5860 +3 7464 1685 2699 +3 1168 5864 2343 +3 5866 5864 5867 +3 3871 3903 5868 +3 2474 6196 5152 +3 4333 5662 6518 +3 3641 3526 5870 +3 7150 1541 1721 +3 3321 1124 2627 +3 936 3778 5880 +3 2186 5288 5474 +3 5288 2186 6647 +3 5883 1171 5887 +3 5887 1171 6590 +3 4987 5307 5889 +3 4464 4462 5890 +3 5890 5889 5891 +3 5735 3745 5897 +3 5897 5896 5898 +3 1101 5702 3639 +3 1172 5899 2612 +3 5899 1172 5065 +3 5697 3754 2386 +3 2612 4226 1172 +3 5268 5292 5902 +3 5902 5901 5905 +3 4851 5147 628 +3 2839 5696 5362 +3 3436 5471 5909 +3 1699 3445 5693 +3 2581 3707 1238 +3 5681 5682 5392 +3 2927 4522 5912 +3 4415 5226 5913 +3 5357 3440 5914 +3 5913 5912 5914 +3 1175 5915 5916 +3 1059 4041 2628 +3 5915 1175 4710 +3 5275 890 5677 +3 4306 7278 5676 +3 5007 5917 7476 +3 5917 231 7053 +3 1685 669 757 +3 5284 1178 5920 +3 5920 1178 1570 +3 6371 1693 6369 +3 5672 4518 917 +3 1570 4898 5920 +3 1084 4866 5091 +3 1182 5921 2461 +3 5921 1182 1185 +3 1184 1183 5923 +3 5925 1184 5923 +3 5923 1185 1182 +3 5664 5665 4068 +3 6813 972 3702 +3 1182 5925 5923 +3 1693 1820 384 +3 2677 1434 5929 +3 4386 1186 5930 +3 1186 4387 2624 +3 5930 1187 4386 +3 4013 4934 5931 +3 5433 3479 6052 +3 6366 1695 5540 +3 5931 1187 1613 +3 5932 4978 727 +3 5677 6712 5275 +3 5930 5932 1613 +3 1191 1188 5131 +3 5002 1189 5933 +3 5933 1191 6300 +3 4381 5935 3380 +3 5937 2466 785 +3 5937 1246 4960 +3 2429 224 5939 +3 1246 1248 5939 +3 3520 5901 5941 +3 7220 5661 2050 +3 5293 4392 5945 +3 5945 5944 463 +3 5947 5946 5963 +3 1695 951 539 +3 5951 1197 5947 +3 5947 1197 1681 +3 2212 5892 1060 +3 4012 4065 6364 +3 1198 432 5951 +3 4012 1733 726 +3 1494 5029 2747 +3 6501 1739 6159 +3 5880 1202 5957 +3 5957 1202 222 +3 5957 1203 5880 +3 5958 1203 6048 +3 5959 1203 5957 +3 2579 2628 5962 +3 5962 1204 488 +3 5946 5093 5963 +3 5963 1204 4811 +3 6159 1739 6210 +3 6632 4568 5656 +3 621 5172 5964 +3 5964 1204 5962 +3 5965 5033 659 +3 1206 5965 3612 +3 5965 1206 1274 +3 1541 462 1088 +3 1741 2672 6240 +3 2143 1211 1274 +3 466 1750 6176 +3 6435 1591 7 +3 5502 5506 5968 +3 5522 1213 1900 +3 2953 882 1436 +3 5971 1214 551 +3 5971 5970 5973 +3 3465 3466 5974 +3 3424 4530 5980 +3 6176 1750 451 +3 5983 4733 793 +3 4767 5954 5986 +3 1218 1217 5988 +3 1218 5988 6045 +3 5990 4057 1222 +3 3335 3623 5993 +3 5376 5427 4840 +3 3822 4962 5995 +3 950 3307 5998 +3 5333 1223 6001 +3 4089 4874 6002 +3 470 4357 2374 +3 470 6003 472 +3 6002 6001 6003 +3 3204 1250 6138 +3 1226 926 1249 +3 1249 5254 1226 +3 1570 2635 1230 +3 1230 1227 1570 +3 6009 1229 1812 +3 4813 6009 1812 +3 6009 2637 1230 +3 97 2635 794 +3 6518 4037 4333 +3 5076 3435 6014 +3 6199 1783 1631 +3 1783 2656 3157 +3 1234 4286 1231 +3 4332 4331 6023 +3 1234 1232 6023 +3 6051 6470 2570 +3 6023 1232 7475 +3 1232 1234 1231 +3 2805 5640 3049 +3 1231 6025 1232 +3 350 1235 3482 +3 4908 1236 6029 +3 6029 1236 1000 +3 6028 6026 6029 +3 6020 862 6030 +3 4055 5656 6031 +3 4440 4857 4649 +3 6036 1677 6762 +3 1255 2640 1238 +3 2138 1238 3707 +3 1098 1237 5686 +3 5686 6037 1098 +3 6040 6675 6236 +3 1385 1429 6041 +3 1853 6685 1710 +3 596 6042 7454 +3 1385 1387 6042 +3 6619 6852 5638 +3 1789 6180 2552 +3 1240 1357 2766 +3 6045 3510 1218 +3 6045 2633 7436 +3 5655 4113 6047 +3 6047 6046 7336 +3 1241 6050 4754 +3 1241 3713 3690 +3 6180 1789 1792 +3 1040 2312 6055 +3 1242 6055 6455 +3 6055 1242 1040 +3 3721 3922 6057 +3 3547 3239 6059 +3 6058 6057 2971 +3 3406 5119 6060 +3 6060 1243 6061 +3 5631 5634 2011 +3 5629 1412 1766 +3 5556 5557 6061 +3 6061 5267 6060 +3 43 6062 1245 +3 1351 1245 6062 +3 1351 3171 6066 +3 1247 4309 6068 +3 1247 2644 6071 +3 1248 1246 5937 +3 5937 6072 1248 +3 2644 1247 6072 +3 6072 1247 6068 +3 1248 6072 6068 +3 1249 6073 1250 +3 4871 2983 2093 +3 1250 6073 6209 +3 1591 5952 6736 +3 1792 6182 4741 +3 4801 6074 690 +3 1304 1305 6074 +3 282 1254 3437 +3 282 3437 2240 +3 2640 1255 413 +3 6077 6075 6078 +3 4613 1256 6080 +3 1256 137 2647 +3 1265 1257 6080 +3 6080 1257 4613 +3 485 3427 5627 +3 5497 4419 5306 +3 1265 1260 6082 +3 6082 1260 3348 +3 5827 5607 3348 +3 5424 889 703 +3 1260 1265 6080 +3 7215 5695 4917 +3 1260 6080 2647 +3 5629 3427 1412 +3 5197 3194 6089 +3 87 819 6090 +3 1266 1271 6092 +3 1266 4852 4582 +3 4090 3567 6092 +3 1271 17 6092 +3 17 1271 6094 +3 4349 4345 6097 +3 526 1510 4228 +3 929 1272 6098 +3 6098 1272 5372 +3 8 6564 5620 +3 1274 1206 2143 +3 1206 6099 2143 +3 6182 1792 1789 +3 3940 1047 3108 +3 1043 6100 1276 +3 6099 6098 6100 +3 6101 4783 6667 +3 6101 7267 2956 +3 2956 2084 6101 +3 2648 2084 1279 +3 5121 1279 2084 +3 1279 2245 2648 +3 1102 6136 1343 +3 4819 3839 6106 +3 4126 4125 6107 +3 3542 4310 6108 +3 1072 6698 2575 +3 6107 6106 6108 +3 1796 3050 4238 +3 1281 3927 6112 +3 1281 1283 3235 +3 2685 5611 2 +3 1065 11 7128 +3 5682 3252 6111 +3 6111 1283 2171 +3 3348 6083 5827 +3 6754 1282 6112 +3 6112 1283 1281 +3 6113 1284 5220 +3 6088 6426 4066 +3 6113 2114 6981 +3 6114 439 4243 +3 6114 2114 439 +3 6116 1585 6802 +3 5860 5886 6119 +3 5783 5782 6120 +3 5776 5777 6122 +3 6120 6119 6122 +3 6125 3980 247 +3 3536 4208 6126 +3 3952 3953 6128 +3 6126 6125 4799 +3 4902 3485 6129 +3 5635 4409 6133 +3 6133 6131 6135 +3 6136 5384 1343 +3 6137 5407 1422 +3 825 2890 6139 +3 5183 5867 6140 +3 6095 6097 6141 +3 4872 6142 7051 +3 6141 6140 6142 +3 5487 5486 6145 +3 542 4302 1547 +3 5039 4766 1547 +3 1956 3913 2831 +3 4707 3973 6149 +3 3725 4407 6151 +3 2525 2456 6426 +3 6155 6154 6157 +3 813 393 5956 +3 1063 5601 2015 +3 2728 1286 6160 +3 6161 1438 6457 +3 6054 3644 6167 +3 6163 6161 6167 +3 3273 1288 6169 +3 2693 1289 6169 +3 4958 6588 5600 +3 1289 6782 210 +3 3300 1290 6170 +3 1290 3408 6170 +3 6170 1380 3300 +3 518 1291 4437 +3 4437 6174 518 +3 4942 4397 6175 +3 466 6176 3981 +3 451 6174 6176 +3 3809 3810 6177 +3 3982 567 6178 +3 2655 1001 6178 +3 4239 2655 1292 +3 6180 4238 723 +3 4741 3673 1792 +3 6144 6145 6183 +3 1789 6183 6182 +3 5641 5640 6184 +3 6846 1805 1899 +3 394 2651 6186 +3 3994 6185 2805 +3 3144 5940 6832 +3 4070 4198 6188 +3 4631 4946 6190 +3 6188 6187 6190 +3 6151 6149 6194 +3 609 39 6195 +3 1297 1296 6195 +3 6193 6194 6198 +3 1297 6195 2656 +3 1783 6199 2656 +3 3260 4416 6202 +3 6202 6201 6203 +3 6089 6090 6204 +3 783 1210 435 +3 2565 3363 5059 +3 3346 2331 7508 +3 4876 5019 6205 +3 4566 5881 5694 +3 1298 6206 1299 +3 6206 1298 5193 +3 7243 4635 6982 +3 1303 1299 6206 +3 1299 5194 1298 +3 1303 1302 6207 +3 6207 1302 5928 +3 1302 1303 6208 +3 6208 1303 6206 +3 1305 1304 6209 +3 6209 1304 1250 +3 1875 1305 6209 +3 783 435 7163 +3 2843 5587 1156 +3 1805 1891 2314 +3 4704 1875 1310 +3 6162 1812 1229 +3 1306 1310 2112 +3 6213 6212 6216 +3 6819 1311 1594 +3 1311 4071 2327 +3 3797 1602 4570 +3 1812 1228 4813 +3 6217 6219 421 +3 6647 3714 256 +3 6335 4249 824 +3 6220 98 5525 +3 6221 5525 98 +3 6442 2032 6221 +3 6223 1319 5503 +3 2544 2534 7211 +3 445 5205 6224 +3 1319 2055 6224 +3 1319 6225 5290 +3 6225 1319 6223 +3 1320 7511 7517 +3 6222 6171 3038 +3 3115 4317 6227 +3 5579 5580 4750 +3 6227 6226 6229 +3 4001 6124 6232 +3 3854 6779 5578 +3 834 1322 2668 +3 6067 7042 1894 +3 5995 5993 6234 +3 1741 3092 6239 +3 2753 1586 6240 +3 1741 6240 1586 +3 2669 1324 6242 +3 6242 1324 5127 +3 1053 5574 2250 +3 6335 1818 6334 +3 6239 2672 1741 +3 6239 6242 2672 +3 6244 6243 6245 +3 5716 3524 5099 +3 1048 1820 6370 +3 1327 3207 3533 +3 2673 4505 1327 +3 3654 3915 6248 +3 3698 3699 6249 +3 6249 6248 6251 +3 1041 6252 4277 +3 1049 5567 372 +3 6252 1340 459 +3 1820 1693 365 +3 1331 6254 5231 +3 6254 1331 1334 +3 6256 1333 6255 +3 6255 1333 5753 +3 4807 3080 1333 +3 6255 1334 6256 +3 6256 1334 1331 +3 5362 1515 2839 +3 4713 3918 6260 +3 99 1335 2710 +3 6470 3284 648 +3 1043 2143 6099 +3 1341 1337 6261 +3 6261 1337 1846 +3 6263 4342 1195 +3 1341 2679 6263 +3 6253 1340 6269 +3 6269 1340 6252 +3 2679 1341 6269 +3 4570 1602 3906 +3 1341 6261 2678 +3 5267 6061 5557 +3 2678 6253 6269 +3 6272 3397 1885 +3 1345 2576 6274 +3 2681 1976 6274 +3 1826 6376 4450 +3 5550 5551 5216 +3 1610 3696 4999 +3 1347 976 2234 +3 3778 1348 6278 +3 6280 1349 6278 +3 6549 3939 7441 +3 6278 1349 3778 +3 2559 3065 1439 +3 6636 1253 7318 +3 3171 1351 6280 +3 6280 1351 6062 +3 6278 1347 6280 +3 4042 5090 6281 +3 3241 3704 6283 +3 1174 2570 5863 +3 6285 1352 3011 +3 6281 6285 2168 +3 3546 3411 6286 +3 5076 5075 6288 +3 6288 6286 6290 +3 4929 4927 6291 +3 5077 4784 6292 +3 5735 5733 6295 +3 3623 3622 6298 +3 4233 6237 6299 +3 5540 7041 1698 +3 6298 6295 6299 +3 1353 6307 2266 +3 3479 6976 7484 +3 6307 1353 6303 +3 6307 6303 7202 +3 6308 1359 2683 +3 2684 1700 5003 +3 1700 2684 5893 +3 2684 6309 7387 +3 1359 6309 5003 +3 3663 2596 6313 +3 3531 4046 6314 +3 5357 5358 6316 +3 3809 3782 6317 +3 6316 6314 6317 +3 256 3714 5538 +3 6319 5697 5694 +3 6322 6292 770 +3 2632 1360 1322 +3 715 1361 6324 +3 6324 6323 414 +3 6028 1362 6325 +3 1362 5611 2685 +3 6325 2147 6028 +3 6376 1826 6378 +3 2602 5568 7305 +3 7221 1851 1563 +3 1370 2994 4698 +3 5532 1567 6977 +3 1368 6330 1369 +3 461 2686 6330 +3 6331 1369 6330 +3 1762 1851 2122 +3 1369 4597 1368 +3 1014 1011 2602 +3 1392 1395 6331 +3 6330 1370 6331 +3 4164 3266 3182 +3 593 6335 401 +3 6335 6334 724 +3 6695 5528 1003 +3 803 3868 5298 +3 5526 5098 4580 +3 7372 5070 7368 +3 1853 1073 4949 +3 1760 2778 2988 +3 1073 1853 6387 +3 3284 6470 1802 +3 6342 4296 116 +3 1372 2213 1374 +3 1373 6343 1375 +3 5387 1860 5384 +3 6342 1374 6343 +3 5384 1860 6390 +3 1877 1076 4488 +3 6343 1374 6340 +3 6340 1375 6343 +3 1375 2946 1373 +3 1801 2502 5996 +3 1030 5520 4105 +3 6348 7304 1822 +3 1376 1913 6349 +3 4538 6351 563 +3 6351 1376 2527 +3 4130 4131 6352 +3 1076 1877 536 +3 1733 6353 4806 +3 4501 6171 3719 +3 5421 6495 5516 +3 3234 5157 4768 +3 5299 5271 6356 +3 6234 6237 6357 +3 5826 4528 6358 +3 4636 3516 6359 +3 6526 1730 1751 +3 6362 3308 1673 +3 6362 6359 678 +3 1695 6366 5543 +3 4134 4133 6367 +3 1698 3935 6368 +3 6367 6366 6368 +3 5410 5411 6369 +3 6370 4248 821 +3 4745 4827 6371 +3 375 1693 6371 +3 6168 2690 100 +3 6168 1379 2692 +3 1027 2549 2620 +3 2684 3560 5893 +3 64 1377 6374 +3 1379 6374 1377 +3 6374 1378 64 +3 1896 35 3926 +3 100 2690 6375 +3 4450 4449 1826 +3 3588 6207 6378 +3 6377 6376 6378 +3 2329 6379 6381 +3 6379 1380 6170 +3 649 1031 900 +3 6381 1383 2329 +3 1384 644 3746 +3 1318 649 6381 +3 5907 1384 2798 +3 2065 4645 547 +3 6499 4573 6383 +3 5968 5506 2611 +3 5450 5244 2904 +3 5228 3259 6384 +3 4298 1389 6384 +3 1387 1385 6385 +3 1828 2865 6813 +3 6385 1385 6041 +3 610 6854 5501 +3 6386 1387 6385 +3 6385 1389 6386 +3 5495 5496 1135 +3 6387 1390 1073 +3 5406 4596 6388 +3 1395 1392 6392 +3 6392 1392 5355 +3 1022 3930 610 +3 6392 6390 1860 +3 1393 6388 1220 +3 13 6145 5486 +3 1395 6392 1393 +3 1396 6393 1400 +3 1396 4105 2698 +3 1400 3907 1396 +3 5764 1397 6395 +3 6395 1400 7102 +3 35 1896 1482 +3 1659 1655 308 +3 2920 1917 6449 +3 6393 236 2207 +3 5953 5799 6397 +3 6405 3117 5107 +3 3624 1403 543 +3 1403 4030 540 +3 510 1404 6407 +3 6407 1404 2702 +3 5953 5954 6412 +3 6413 6208 4183 +3 3729 5994 4082 +3 1405 6413 4142 +3 308 1655 4673 +3 1406 6415 1409 +3 6415 1406 6377 +3 6416 1409 6415 +3 1409 4509 1406 +3 5048 3632 5393 +3 299 6416 2374 +3 6415 1405 6416 +3 444 1659 1887 +3 6417 1413 4980 +3 362 4980 2064 +3 1414 6418 1415 +3 6418 1414 1944 +3 408 6420 4541 +3 1415 2044 1414 +3 1917 6448 6450 +3 408 1417 6420 +3 6422 6421 6424 +3 6430 3113 1086 +3 5388 2540 7146 +3 6431 6430 6432 +3 295 1418 3635 +3 3635 6433 295 +3 1419 6433 2286 +3 6433 1419 1425 +3 4983 1421 6434 +3 1421 3676 2706 +3 1959 6471 530 +3 1959 6468 6467 +3 5209 5210 6436 +3 6434 1425 6436 +3 6436 1425 1419 +3 4306 5676 1018 +3 4898 2617 7341 +3 4802 1962 6500 +3 2707 6438 787 +3 6500 1962 7252 +3 5476 2813 6539 +3 6438 6915 908 +3 6041 1429 522 +3 903 898 3212 +3 522 6439 6041 +3 3076 5227 6440 +3 3946 4478 6441 +3 6440 6439 6441 +3 1433 6153 6949 +3 2942 1431 6443 +3 1431 6360 1433 +3 1432 6443 1431 +3 6443 1432 2416 +3 5916 5915 6444 +3 1432 1433 6444 +3 1015 5481 4648 +3 6444 1433 6949 +3 1434 2677 6445 +3 101 6446 2711 +3 6723 2275 3044 +3 1013 5459 218 +3 5308 1968 3616 +3 5737 5736 6448 +3 3442 2920 6449 +3 3667 3611 6450 +3 6450 6449 1917 +3 6013 6014 6452 +3 4637 4636 6453 +3 6452 6451 6453 +3 6455 6055 2642 +3 6455 1439 1242 +3 4819 4823 6456 +3 6456 1439 3065 +3 4602 2268 1428 +3 1438 1038 2559 +3 6457 1439 6455 +3 5800 3660 5809 +3 1968 2641 6574 +3 1440 5809 3660 +3 2739 2307 1427 +3 5051 1442 6462 +3 1440 6462 6460 +3 3588 1969 6525 +3 1447 2715 6465 +3 4490 1443 6466 +3 3561 2715 6466 +3 1887 1659 308 +3 674 1694 2311 +3 6466 1608 4490 +3 4843 1451 6467 +3 1426 6039 190 +3 342 879 2208 +3 530 3391 1959 +3 1963 3152 2393 +3 6365 3582 4325 +3 6467 6471 1959 +3 3689 6472 337 +3 7427 3139 7364 +3 2952 2836 4147 +3 6474 1454 6218 +3 3537 4737 6476 +3 3550 1455 3549 +3 273 6477 3550 +3 3937 1457 187 +3 187 6480 3937 +3 5452 5919 2519 +3 6480 6477 273 +3 5451 1769 2133 +3 5442 127 3281 +3 3407 3478 6484 +3 5350 5349 6486 +3 5534 3820 6488 +3 6203 5711 6489 +3 2389 4274 6102 +3 6488 6486 6489 +3 4785 1458 6491 +3 5151 264 6492 +3 5539 6493 4926 +3 6492 6491 6493 +3 2668 7086 834 +3 5481 2615 5022 +3 6354 88 2948 +3 2311 1694 5276 +3 106 7508 4023 +3 3283 3309 6496 +3 4886 1461 6496 +3 1008 2081 4512 +3 1459 6497 1460 +3 6497 1459 6058 +3 651 1969 6528 +3 6498 1460 6497 +3 1460 5738 1459 +3 5441 5444 1795 +3 4971 1460 6498 +3 6497 1461 6498 +3 2802 5581 5438 +3 1539 4382 2303 +3 6159 5822 6501 +3 1977 6543 6541 +3 1464 7251 3506 +3 1464 1465 2772 +3 1465 1058 7185 +3 2720 3028 6507 +3 2720 3543 2659 +3 1471 1468 6507 +3 6177 6451 6508 +3 2541 1816 5758 +3 3438 3782 6509 +3 6509 6508 6510 +3 6515 1474 6516 +3 6516 1474 6514 +3 6514 1473 6516 +3 909 3775 910 +3 6000 5539 5066 +3 3330 4992 6519 +3 3566 3565 6522 +3 4643 4128 6524 +3 6522 6519 6524 +3 1155 1682 6525 +3 1325 4791 6527 +3 5324 5325 6528 +3 792 1623 6567 +3 642 651 6528 +3 4767 6243 6529 +3 3656 7486 5428 +3 5713 5632 3524 +3 6532 1475 3362 +3 6532 1476 6531 +3 6531 6533 6532 +3 6531 1477 6533 +3 1679 6534 1107 +3 4058 3476 6535 +3 3794 5052 2659 +3 3695 4331 6536 +3 6535 6534 6536 +3 4761 7087 6540 +3 5795 5794 6543 +3 6541 6544 1977 +3 2596 6545 6312 +3 1165 5420 4297 +3 4461 1523 6551 +3 4863 2305 6553 +3 5767 2495 6553 +3 447 2010 381 +3 7518 2700 5872 +3 2011 5195 5196 +3 2723 1832 1480 +3 5526 6344 2192 +3 1480 1478 3397 +3 1480 3398 1478 +3 5195 2011 5634 +3 6557 3302 746 +3 5415 5416 6721 +3 5189 2016 4100 +3 2016 3331 2037 +3 7337 6557 1832 +3 5063 2035 832 +3 4510 749 4756 +3 6403 4502 6560 +3 6559 6558 6560 +3 5830 3822 6561 +3 6357 6356 6563 +3 6562 6561 6563 +3 5621 5620 6564 +3 142 4721 6566 +3 6886 6369 5411 +3 882 2953 635 +3 3699 5795 6568 +3 2726 1487 6569 +3 6569 1487 1572 +3 1572 1490 6569 +3 2035 5062 126 +3 2758 6052 2590 +3 2748 1492 6570 +3 1492 1571 2446 +3 2446 6570 1492 +3 5659 1494 6760 +3 5467 1495 6572 +3 5408 3570 443 +3 6572 1495 5849 +3 5731 6573 5072 +3 1326 5958 314 +3 6576 4487 997 +3 1678 6577 6576 +3 1497 6582 4759 +3 5387 6137 5406 +3 6583 5464 1089 +3 6582 6578 6583 +3 948 1501 6590 +3 7311 7264 5405 +3 1503 6590 1171 +3 6590 1503 1507 +3 1946 2505 2603 +3 1505 1504 6591 +3 6592 1505 6591 +3 6591 2729 1507 +3 1503 6592 6591 +3 4100 4099 6596 +3 2132 1808 2040 +3 3252 3100 6597 +3 3566 3235 6598 +3 4773 2973 6599 +3 6598 6597 6599 +3 2663 6897 2280 +3 3692 6602 4251 +3 6602 6601 6603 +3 1552 249 1274 +3 2538 2630 5767 +3 5767 6553 2538 +3 2902 2838 7343 +3 1465 1464 6502 +3 6502 6605 1465 +3 1509 6607 983 +3 1509 3203 4312 +3 1911 2783 6521 +3 983 4543 1509 +3 5395 5398 1985 +3 292 4781 6608 +3 1698 3579 6015 +3 6611 3163 691 +3 6610 6611 6613 +3 6260 6259 6614 +3 6614 6613 6616 +3 997 2046 1678 +3 6618 2619 6977 +3 984 5390 4299 +3 3478 4603 6620 +3 5005 4489 6623 +3 6622 6620 6623 +3 2858 5386 5031 +3 3058 2924 6624 +3 1181 6625 6624 +3 2284 6625 1517 +3 53 2308 2646 +3 1427 2307 3902 +3 6273 7295 6156 +3 6625 2284 2665 +3 6627 1517 6625 +3 2063 6578 6807 +3 6578 2063 6583 +3 6025 2958 6628 +3 3059 2969 6629 +3 3745 3748 6631 +3 6629 6628 6631 +3 3470 3493 6633 +3 5905 5742 6635 +3 6634 6633 6635 +3 1841 5380 2516 +3 4146 6823 5378 +3 3351 5416 6638 +3 2676 7461 7460 +3 3326 3324 6639 +3 6640 3470 2242 +3 6639 6638 6640 +3 3881 3875 6646 +3 5273 5271 6648 +3 6646 6645 6648 +3 1866 2144 7206 +3 4157 5282 6650 +3 6858 6458 2688 +3 4768 4519 2398 +3 1518 6651 574 +3 1518 6172 4768 +3 1519 2731 1520 +3 1519 4184 2731 +3 1520 3534 1519 +3 1522 1520 6655 +3 1524 6655 1520 +3 6655 1524 3129 +3 1524 2762 2592 +3 2362 2077 806 +3 1525 2322 567 +3 3460 1528 6658 +3 6658 1528 5925 +3 2121 1876 1556 +3 102 6658 2735 +3 6658 102 11 +3 5870 1529 6659 +3 6659 1529 5868 +3 6659 1531 5870 +3 2923 1530 6662 +3 4001 3705 5703 +3 6662 1531 300 +3 4456 6485 6663 +3 6663 1531 6659 +3 7244 3602 4460 +3 2077 2102 5847 +3 3547 2079 6684 +3 6684 2079 6683 +3 1328 258 6053 +3 5363 5365 2593 +3 5796 6600 6670 +3 6515 6340 6674 +3 4520 7180 7068 +3 1326 975 5361 +3 4807 6256 5110 +3 1535 7094 6675 +3 1535 2743 6678 +3 4807 2098 5687 +3 2743 1535 6679 +3 6679 1535 6675 +3 6333 6316 5358 +3 1536 6679 6675 +3 6679 1536 6752 +3 165 1538 6681 +3 6681 1538 4832 +3 5402 5664 6682 +3 3546 3547 6684 +3 6683 6682 6684 +3 5083 5084 6686 +3 283 1540 6686 +3 6691 5590 6689 +3 6689 5590 4300 +3 6689 1540 6691 +3 6693 1985 2468 +3 5444 777 4329 +3 4329 6694 1795 +3 971 2113 4517 +3 6936 6486 5349 +3 5528 6695 291 +3 6694 6693 6695 +3 969 5347 6294 +3 4322 6135 6696 +3 5896 2958 6699 +3 6698 6696 6699 +3 4194 3609 5509 +3 6551 6550 6705 +3 1372 6707 5732 +3 1670 6707 1372 +3 6707 1545 4995 +3 6703 6705 6709 +3 5337 5339 6688 +3 1545 6706 6709 +3 601 1548 6711 +3 6548 6547 6712 +3 1549 6405 6713 +3 4342 5556 6714 +3 6714 1549 1665 +3 1556 2033 7519 +3 5373 3612 279 +3 1665 6713 6715 +3 4181 4184 6717 +3 3084 6718 3034 +3 3694 3695 6720 +3 641 2907 4724 +3 7269 1780 5334 +3 1551 3742 4313 +3 3579 1698 7041 +3 1626 2131 6869 +3 1223 3928 472 +3 3821 4351 6725 +3 6869 2131 6873 +3 1616 1308 6159 +3 1711 3507 6143 +3 2745 2139 6727 +3 3507 1711 4426 +3 1819 3472 2190 +3 5560 1555 6728 +3 1555 3298 2745 +3 6727 2138 6728 +3 2138 1558 6728 +3 3255 2135 1631 +3 5396 2703 5388 +3 6728 1558 5560 +3 5605 7275 6730 +3 4475 4474 6731 +3 6397 6398 6733 +3 7004 1556 1876 +3 6733 6731 6734 +3 6739 3332 1177 +3 3432 1559 1013 +3 6739 6737 6740 +3 965 5328 4930 +3 2648 2245 246 +3 193 1562 2209 +3 1631 2135 6947 +3 6742 6741 922 +3 5891 5798 6745 +3 5325 2279 642 +3 3849 4464 6746 +3 6746 6745 6748 +3 2469 5454 3989 +3 6146 2172 6989 +3 6751 1564 6924 +3 964 2848 1870 +3 1929 1533 2743 +3 576 5874 2021 +3 2518 5848 3784 +3 6750 6752 1536 +3 3174 3103 6753 +3 4638 4890 6755 +3 6996 5315 5314 +3 961 5874 5321 +3 6755 6753 6756 +3 4435 1565 6759 +3 1565 2747 5029 +3 6989 2172 2201 +3 6760 6572 6546 +3 6579 1907 1560 +3 1569 6760 2747 +3 6760 1569 6572 +3 4249 2176 824 +3 1565 4435 3253 +3 2194 2282 6762 +3 648 6974 6270 +3 4157 5302 6768 +3 6769 2635 1178 +3 1487 1571 1492 +3 1492 6770 1487 +3 2088 5641 6184 +3 6770 1572 1487 +3 4808 5733 6772 +3 5898 6131 6775 +3 6838 5308 3616 +3 6774 6772 6775 +3 1577 1573 6776 +3 6776 1573 2383 +3 1578 1577 6776 +3 5990 5783 6777 +3 4247 2176 1108 +3 3746 3505 2204 +3 6989 2201 7028 +3 7028 2201 7312 +3 6778 3854 1855 +3 5577 5578 6779 +3 2516 171 1841 +3 5510 6601 6780 +3 6779 6778 6780 +3 2161 5778 4964 +3 6737 6079 6783 +3 395 1580 6784 +3 3052 3088 6785 +3 2738 6784 3433 +3 1479 5621 5302 +3 5323 4913 6786 +3 1581 6786 4913 +3 1581 6788 2751 +3 6904 3340 4098 +3 6791 1582 6788 +3 5297 5299 5461 +3 6788 1582 1867 +3 3302 3721 1582 +3 2209 410 193 +3 6791 6788 1581 +3 2344 1584 560 +3 6219 5672 6796 +3 6472 6474 6798 +3 6581 5493 5295 +3 917 5394 6799 +3 251 6796 6799 +3 860 1645 6801 +3 2445 1586 6805 +3 1946 7148 6758 +3 6805 2753 6804 +3 6805 103 2442 +3 2127 6806 1482 +3 103 2752 6806 +3 410 2209 580 +3 5291 5292 4786 +3 6807 4420 2754 +3 5154 5527 3585 +3 6807 1588 2063 +3 6808 2754 1589 +3 2757 1588 6808 +3 6808 1588 6807 +3 895 2214 7056 +3 6808 1589 2750 +3 6811 5234 1995 +3 2214 7055 7059 +3 5553 356 7524 +3 2215 906 5241 +3 3902 2307 1110 +3 6814 1593 1592 +3 1593 5186 1592 +3 6649 1594 6818 +3 4646 3646 697 +3 2925 3536 6819 +3 6831 1601 1595 +3 3275 3274 6820 +3 5078 4476 4573 +3 3340 3457 3562 +3 6821 6634 5829 +3 6822 2592 2762 +3 6822 1596 1135 +3 5379 5378 6823 +3 906 2215 7059 +3 6823 1596 4583 +3 3672 5484 4583 +3 6824 1596 6822 +3 2763 1598 6825 +3 6825 1598 6826 +3 6826 1597 3853 +3 3853 6825 6826 +3 6826 1598 1641 +3 4250 4252 6827 +3 5454 2469 5457 +3 4223 4222 6828 +3 4588 3449 6829 +3 2766 6372 6829 +3 2761 3660 6831 +3 1996 1601 6831 +3 6765 6764 6835 +3 5307 5308 6838 +3 5799 5798 6839 +3 6838 6835 6839 +3 6845 4650 6847 +3 4014 3553 6848 +3 6848 4650 6845 +3 6290 6201 6849 +3 6510 3435 6851 +3 3967 574 5282 +3 5636 5638 6852 +3 6851 6849 6852 +3 6853 610 3360 +3 7380 2221 1600 +3 3231 2986 6855 +3 6854 6853 6855 +3 3174 3175 6856 +3 6859 1168 2343 +3 2221 7093 20 +3 1805 6846 5149 +3 7127 3593 4632 +3 2564 5280 7155 +3 6859 2343 2342 +3 5330 6010 6862 +3 2794 1342 809 +3 794 1606 6862 +3 6864 1605 4280 +3 4580 2118 4117 +3 6864 1604 5487 +3 4028 1987 662 +3 6866 1605 6864 +3 4280 1604 6864 +3 6769 6768 6866 +3 6864 1606 6866 +3 1201 5185 6688 +3 6870 6869 6873 +3 2229 7132 5969 +3 3472 1819 2179 +3 1612 6874 1018 +3 6874 1612 1671 +3 6876 4702 6915 +3 681 2398 441 +3 4851 1615 6877 +3 6402 1616 6878 +3 1616 6158 123 +3 50 6878 1942 +3 1620 7225 5571 +3 7158 1680 685 +3 2241 7157 7160 +3 1619 1671 5558 +3 156 939 4899 +3 7429 2246 1550 +3 7104 2737 3921 +3 5985 7508 106 +3 4195 1621 6887 +3 6887 7112 2352 +3 2352 7112 6587 +3 1021 6648 5271 +3 4079 4810 6889 +3 5330 6144 6891 +3 6890 6889 6891 +3 5710 3522 2488 +3 6881 1664 6893 +3 297 1885 1478 +3 3830 3829 6895 +3 4285 2119 6900 +3 6562 4919 6905 +3 5615 5828 6907 +3 3836 5107 6910 +3 1478 1885 3397 +3 7209 2246 7212 +3 6915 1622 2936 +3 3481 5245 6916 +3 6916 1622 6912 +3 5217 6627 6918 +3 2924 4586 6919 +3 6258 6908 6925 +3 6921 6920 6925 +3 6318 6927 6612 +3 3329 4210 6928 +3 6927 6926 6928 +3 5900 6921 6929 +3 1625 6931 1732 +3 6931 1625 2030 +3 6932 6931 6933 +3 5894 1742 6934 +3 7169 1895 3390 +3 1742 2060 6934 +3 6596 1628 6937 +3 6937 1628 6595 +3 6937 1629 6596 +3 6938 5564 5565 +3 5068 4476 5078 +3 229 1629 6939 +3 5730 4078 6939 +3 6939 2975 229 +3 6939 1629 6937 +3 6521 2553 3002 +3 3002 2553 6744 +3 1840 3958 1630 +3 6765 4487 6942 +3 1840 6593 6942 +3 3818 6945 1587 +3 2251 7277 4264 +3 7277 2251 7276 +3 6946 1632 2135 +3 5734 5446 5262 +3 2529 5260 936 +3 6199 1631 6947 +3 1587 6945 2776 +3 2777 1634 7034 +3 7034 1664 2777 +3 5188 6951 5750 +3 1636 1635 6951 +3 6951 1635 6399 +3 2263 3356 828 +3 1635 1636 2777 +3 2777 1636 1634 +3 935 5257 721 +3 5606 1637 6953 +3 1637 4335 6580 +3 6953 6660 4762 +3 6953 1638 5606 +3 3400 3395 5385 +3 4514 4515 6955 +3 237 6956 492 +3 4974 3815 6943 +3 4314 6308 6961 +3 3356 2263 2068 +3 2027 257 135 +3 6960 6958 6961 +3 3241 4168 6962 +3 3187 3185 6964 +3 5534 5667 6966 +3 6964 6962 6966 +3 6967 1640 6970 +3 6970 1640 4979 +3 5202 5252 2326 +3 2264 7357 1843 +3 4402 3483 6971 +3 1748 1643 6972 +3 6972 1643 5753 +3 1706 4202 6975 +3 5201 708 985 +3 6974 6972 6975 +3 7357 2264 7356 +3 2268 7375 7029 +3 3655 3654 6984 +3 4521 4522 6985 +3 6985 6984 6986 +3 5612 6669 6987 +3 352 1644 6991 +3 4585 3402 6992 +3 5232 4314 6995 +3 1646 2820 7282 +3 3159 3158 6997 +3 1646 6084 6997 +3 6084 1646 7001 +3 2244 4376 6792 +3 7001 1646 7282 +3 7375 2268 7446 +3 1647 3611 2781 +3 3761 4804 3277 +3 3297 2885 6729 +3 908 2507 1541 +3 2087 7314 608 +3 1648 3443 1647 +3 5239 5240 3558 +3 4069 3528 7003 +3 1031 3205 3765 +3 7003 1648 2999 +3 7005 1648 1647 +3 5523 4761 7008 +3 1649 1785 1651 +3 6067 3971 5235 +3 1895 1177 3332 +3 1903 3366 6994 +3 812 6685 4949 +3 5153 2276 2081 +3 2081 2276 3045 +3 2281 5797 2226 +3 1658 1656 7020 +3 1656 1309 7023 +3 1309 1762 180 +3 7021 7020 7023 +3 5818 1657 7024 +3 1656 1658 2599 +3 5370 6944 7026 +3 6917 6155 7027 +3 6987 6989 7028 +3 1964 6811 1995 +3 1662 7031 2785 +3 7031 1662 7029 +3 7029 1663 7031 +3 7031 1663 2030 +3 897 5232 3189 +3 5789 7033 147 +3 5797 2281 146 +3 3947 7034 1634 +3 2694 7033 7057 +3 5654 3947 1666 +3 1169 7035 5229 +3 1060 1140 1561 +3 6980 6979 7036 +3 5226 5227 4581 +3 7419 7397 2372 +3 1553 2300 7432 +3 1667 4234 1669 +3 1667 1669 7040 +3 7157 2301 284 +3 3395 3400 1332 +3 7040 1669 6671 +3 3366 1903 5583 +3 1657 7044 7024 +3 7044 29 30 +3 30 7024 7044 +3 3950 6909 6523 +3 7046 1671 1612 +3 1935 3049 4696 +3 2587 664 3006 +3 7046 1672 5288 +3 1672 7047 5474 +3 7047 1672 2094 +3 2301 7429 284 +3 7048 4910 2051 +3 7048 1676 4910 +3 71 2303 4382 +3 1085 7049 1937 +3 1675 7049 1674 +3 7049 1675 1937 +3 1675 1676 7050 +3 1676 7048 2789 +3 2791 2194 1754 +3 1677 1754 2194 +3 2791 6230 2399 +3 2792 4187 897 +3 3299 3200 7055 +3 7056 4095 895 +3 1681 7059 6228 +3 7059 1681 906 +3 7059 7056 2214 +3 2303 7497 1539 +3 2406 2371 7061 +3 2371 2406 2555 +3 894 1284 2302 +3 1516 5706 495 +3 7063 2052 181 +3 5091 2316 5754 +3 5414 5594 2504 +3 2755 1960 5123 +3 5123 1960 637 +3 2323 7240 1532 +3 5252 3006 4039 +3 4904 1688 7067 +3 1688 3168 2796 +3 109 7067 2796 +3 7067 1689 4904 +3 107 5907 2798 +3 6678 5236 7069 +3 107 2797 7069 +3 4798 6610 7070 +3 4080 6187 7071 +3 7058 7431 5547 +3 6259 3056 7072 +3 5670 1879 5787 +3 7427 1639 3139 +3 7071 7070 7072 +3 6154 4515 7076 +3 119 2323 5926 +3 4635 5658 5761 +3 7079 1080 4635 +3 4892 4649 7426 +3 5270 2324 5571 +3 233 6434 6436 +3 2324 5834 1620 +3 68 2801 7078 +3 7377 5130 6264 +3 5393 3632 5352 +3 5003 1700 7080 +3 7080 1700 1702 +3 1701 2683 7080 +3 5823 6960 7081 +3 2610 5027 2210 +3 1701 2804 7081 +3 2804 1701 7082 +3 7082 1701 7080 +3 3499 2236 1320 +3 2345 1703 7083 +3 2590 1132 6311 +3 6994 2650 1047 +3 4032 4031 7090 +3 2699 4599 7464 +3 7093 7090 7094 +3 3074 3080 7097 +3 355 1705 7098 +3 722 2712 7005 +3 15 4081 5197 +3 7098 7097 7099 +3 7105 3844 3845 +3 4202 1706 7106 +3 885 1035 2543 +3 7106 1706 4108 +3 4106 4107 7107 +3 2660 5193 161 +3 6379 2329 1380 +3 5192 2670 4299 +3 2876 3683 2438 +3 2329 1383 6380 +3 2154 2345 7083 +3 1610 2421 513 +3 2295 1709 7114 +3 4061 5565 5189 +3 7114 1709 70 +3 2350 6147 7458 +3 2269 6584 7123 +3 5609 7125 1066 +3 7125 5609 1065 +3 411 75 7126 +3 102 2732 7128 +3 7126 7125 7128 +3 4467 7131 1012 +3 5969 5968 2229 +3 3632 3444 5814 +3 3003 3379 7133 +3 2873 3926 5187 +3 6147 2350 6210 +3 2229 7133 7132 +3 546 1714 7134 +3 6616 4567 7135 +3 4714 4713 7137 +3 7135 7134 7137 +3 6908 6909 7142 +3 319 756 872 +3 6930 6929 7144 +3 2299 733 5222 +3 2507 1716 462 +3 4344 4345 7152 +3 1719 7154 1721 +3 2314 6400 1899 +3 1719 3544 2806 +3 7152 1720 7154 +3 1592 6766 5437 +3 7154 1720 7150 +3 7150 1721 7154 +3 1721 4598 1719 +3 5823 7160 6017 +3 7160 7158 2241 +3 7124 5337 5184 +3 4655 4653 7161 +3 5986 6734 7162 +3 3046 6245 7164 +3 5106 733 2645 +3 7162 7161 7164 +3 491 6833 7165 +3 7165 4373 491 +3 5942 1277 7165 +3 4373 7165 21 +3 5027 2610 5181 +3 1724 5013 2807 +3 1728 7169 82 +3 3390 4388 7169 +3 2263 2351 5418 +3 82 7168 1728 +3 5829 5742 5177 +3 217 1527 4924 +3 1941 3557 7170 +3 5225 5422 7171 +3 1941 5763 7171 +3 5632 3651 3524 +3 6980 1732 7172 +3 7172 1732 6932 +3 1830 5610 7172 +3 113 1912 6579 +3 7172 5610 6980 +3 1737 686 7176 +3 6407 2702 1737 +3 7176 1738 6407 +3 7177 4284 4307 +3 115 2351 104 +3 7066 1527 7525 +3 7180 7177 7181 +3 1740 7183 6345 +3 7183 1740 1752 +3 1253 1221 7318 +3 7318 1221 2836 +3 2077 2362 4616 +3 4616 2362 2105 +3 7498 5298 305 +3 3222 4112 2914 +3 7185 1906 7469 +3 6345 7183 7188 +3 702 2421 1610 +3 629 603 7318 +3 6504 4005 4136 +3 5790 3448 7189 +3 6212 5817 7191 +3 3631 489 6275 +3 3156 5579 7193 +3 7192 7191 7193 +3 5766 1746 7194 +3 5173 5174 3617 +3 2360 7195 442 +3 5172 4811 1204 +3 6566 6564 7196 +3 7194 7196 8 +3 7346 1838 6653 +3 3049 1935 3486 +3 1747 4514 2815 +3 1944 3030 2933 +3 1749 3214 1747 +3 3068 541 4566 +3 7155 1697 3077 +3 2607 1730 1729 +3 1752 7184 7183 +3 1752 2144 7184 +3 3110 1753 7207 +3 7207 1753 1866 +3 7207 7206 7208 +3 4060 7387 2487 +3 5017 3114 2613 +3 1680 1677 7212 +3 2441 2883 7450 +3 7210 7209 7212 +3 4022 4221 7216 +3 7215 7213 7216 +3 874 2370 5745 +3 1755 7217 4587 +3 7217 1755 7271 +3 1757 1756 74 +3 1757 74 1781 +3 2478 4169 5515 +3 6483 5661 7220 +3 544 2032 7113 +3 1759 7220 2050 +3 7220 1759 1940 +3 3126 1430 3832 +3 6348 5750 7223 +3 4719 4718 7226 +3 6538 6537 7230 +3 7015 5721 3145 +3 5163 5164 6969 +3 6756 6229 7231 +3 7230 7226 7231 +3 5063 1763 7232 +3 7232 1763 5768 +3 1190 2734 1427 +3 7332 5165 3172 +3 7232 1767 3359 +3 5449 4765 5336 +3 4209 6828 5162 +3 3821 5660 7233 +3 1767 4176 7233 +3 2266 1764 7234 +3 7234 1764 2175 +3 1767 7234 2175 +3 1767 7232 5768 +3 1752 1768 7235 +3 1768 1749 1747 +3 2554 7236 173 +3 173 179 7238 +3 2784 2941 763 +3 7013 6153 7244 +3 1273 1771 7245 +3 7245 1771 1774 +3 7263 1772 7246 +3 1630 4446 617 +3 1047 2650 5828 +3 6458 5715 3601 +3 7247 7249 108 +3 4880 6088 5157 +3 1830 1773 7249 +3 1773 438 2823 +3 7249 7247 3812 +3 7252 6501 3219 +3 5662 2377 5642 +3 7054 7052 7253 +3 3665 4540 4557 +3 6930 5612 7254 +3 2764 7270 5017 +3 7118 5014 7257 +3 5018 5751 7258 +3 7258 7257 7259 +3 7246 1774 1771 +3 1771 7263 7246 +3 7261 7260 7263 +3 1776 1772 3489 +3 7250 7252 1962 +3 2197 7408 5150 +3 5466 2694 1666 +3 3854 5578 5141 +3 7245 1778 7268 +3 1778 5807 2817 +3 7268 1782 7245 +3 1666 2694 5654 +3 7269 1782 6761 +3 1781 7271 1757 +3 7271 1781 7217 +3 7268 7271 1755 +3 5298 2661 7203 +3 1784 3920 3918 +3 2860 5140 3495 +3 2818 1791 1784 +3 3683 694 1500 +3 2863 4093 761 +3 1651 1785 7273 +3 2819 1786 7273 +3 7512 3893 7141 +3 7273 1786 1787 +3 1786 7274 26 +3 7273 1787 7016 +3 7274 2243 26 +3 26 2233 1787 +3 1786 1791 7274 +3 7274 1791 2818 +3 1955 559 1171 +3 5458 7021 7276 +3 4264 4262 2251 +3 56 2047 2069 +3 5673 5676 7278 +3 1793 7282 2822 +3 7282 1793 7001 +3 7019 5888 2653 +3 7466 369 1323 +3 1897 1794 7284 +3 7284 2820 2675 +3 27 2820 1646 +3 30 7285 1800 +3 2768 7286 2604 +3 7286 1800 2106 +3 1154 1441 6215 +3 7285 7287 2106 +3 3877 3876 7288 +3 128 1803 7289 +3 7289 1803 253 +3 244 6820 6673 +3 7292 7289 253 +3 6797 5061 7280 +3 7293 3527 2824 +3 2824 1806 7293 +3 1806 1811 1807 +3 1807 7293 1806 +3 4197 4838 6034 +3 7293 1807 4652 +3 7155 3077 2258 +3 5619 3929 5087 +3 2825 4470 1809 +3 1809 1811 7295 +3 7295 1811 1806 +3 906 4463 368 +3 1806 5382 7295 +3 7297 2792 3189 +3 7297 7296 2133 +3 5278 153 3119 +3 1056 7368 3934 +3 7300 1817 6189 +3 3921 5604 7104 +3 1815 7300 2827 +3 1815 6906 1817 +3 1817 7300 1815 +3 6744 2768 4129 +3 1924 6652 3254 +3 6784 2738 6785 +3 859 5126 32 +3 2772 196 214 +3 1822 192 6345 +3 1822 7304 1823 +3 7519 4143 5546 +3 1526 3077 1697 +3 2674 6164 353 +3 1823 7304 7442 +3 1823 3214 192 +3 3030 1944 1414 +3 7306 1999 150 +3 6529 6530 7307 +3 6748 6412 7308 +3 2939 3848 7309 +3 1921 943 2722 +3 7308 7307 7309 +3 109 2796 1825 +3 4207 1824 7310 +3 1825 7310 109 +3 6882 4993 2331 +3 2270 5182 5117 +3 854 5112 5364 +3 7310 1825 2353 +3 1989 7312 2201 +3 5381 5380 1841 +3 3121 3386 2563 +3 5244 542 1718 +3 1829 1827 6328 +3 2323 1157 5926 +3 2955 2671 2835 +3 3383 6556 2153 +3 76 2812 2602 +3 2738 6783 1091 +3 1827 1829 171 +3 2181 6401 2904 +3 7316 7315 7317 +3 1773 1830 7323 +3 1830 7172 2811 +3 6801 7287 7326 +3 7329 7328 7330 +3 5499 1449 4562 +3 7120 6410 7331 +3 293 7334 312 +3 7335 6271 1004 +3 4129 2421 6744 +3 5640 2805 6184 +3 541 5057 2269 +3 1832 2723 141 +3 141 7334 7337 +3 2853 2290 6164 +3 1834 1833 7338 +3 848 5104 3797 +3 1833 1619 2793 +3 2542 1987 7339 +3 3026 1268 5253 +3 7339 1834 7340 +3 5515 1991 7202 +3 1835 2406 7061 +3 7340 2837 7339 +3 7340 1834 7338 +3 2406 1835 3469 +3 469 3631 2739 +3 1836 7342 1882 +3 7342 1836 262 +3 7343 2365 1 +3 1837 7343 7345 +3 7343 1837 4292 +3 7345 2839 1837 +3 7345 2838 257 +3 890 5275 2528 +3 7347 7346 5168 +3 164 4996 1391 +3 1839 2396 7349 +3 4839 1839 7349 +3 6398 6764 7350 +3 3674 4475 7351 +3 2494 7109 1850 +3 6593 1840 7352 +3 7352 1840 1630 +3 7351 7350 7352 +3 3091 225 4025 +3 7354 1841 1829 +3 2314 5976 3751 +3 5322 1842 964 +3 964 7355 5322 +3 6710 7356 1051 +3 5234 4817 7359 +3 7357 7356 7359 +3 1844 7360 1845 +3 1844 690 2841 +3 4189 3244 1054 +3 1848 1845 7360 +3 1845 4372 1844 +3 3963 7361 1082 +3 1848 1846 7361 +3 7361 1846 1337 +3 1306 1847 7362 +3 1846 1848 7360 +3 7360 7362 1846 +3 842 1849 845 +3 1293 6931 2030 +3 3603 1575 5393 +3 5097 7363 842 +3 2566 3991 2427 +3 6517 1904 1526 +3 1850 7363 2494 +3 7363 1850 1857 +3 5582 5587 7365 +3 3452 4197 5472 +3 7371 1855 7365 +3 7365 1855 3854 +3 3625 1856 1855 +3 7365 1857 7371 +3 7371 1857 1850 +3 488 5963 5093 +3 5752 1961 1828 +3 2290 4383 353 +3 2805 6185 1064 +3 2630 2538 3792 +3 7029 5458 2268 +3 664 2831 4651 +3 5919 3954 1654 +3 7379 6264 3124 +3 7017 1858 7381 +3 7381 1858 7167 +3 7381 2844 2020 +3 2020 1859 7381 +3 7381 1859 7017 +3 2687 5563 7437 +3 5894 2020 1862 +3 1862 7382 5894 +3 7065 1862 2020 +3 7382 1862 2058 +3 658 2184 4433 +3 254 1865 7383 +3 6686 5084 2177 +3 4037 3134 2045 +3 7388 1863 7384 +3 7384 1863 6302 +3 6332 4300 1863 +3 7384 1865 7388 +3 5705 5082 3659 +3 7238 6956 7391 +3 6830 2737 7104 +3 5426 4894 5705 +3 6880 6810 7393 +3 5046 1914 7393 +3 6660 3306 4017 +3 3659 5426 5705 +3 5369 6157 7395 +3 5149 2447 1805 +3 2881 1978 7395 +3 1980 2014 7396 +3 7184 1866 7398 +3 7324 627 7275 +3 2447 1891 1805 +3 3346 1891 2447 +3 7398 1866 1753 +3 1939 447 7303 +3 7467 1263 7399 +3 5642 4192 7401 +3 6788 1867 1112 +3 1112 7403 2751 +3 7405 7354 2832 +3 1871 1868 7406 +3 7405 1870 7406 +3 7406 1870 7403 +3 7403 1871 7406 +3 5144 5150 7408 +3 7073 7175 7411 +3 5139 1872 7412 +3 7412 1872 6253 +3 4554 6288 5075 +3 4283 1104 6096 +3 5080 5341 833 +3 7412 2851 5139 +3 5255 1873 7413 +3 7413 1873 6592 +3 2227 110 1874 +3 3724 3722 6993 +3 3363 2893 4673 +3 7413 1874 5255 +3 1310 1875 7414 +3 1526 1904 6573 +3 1875 6209 2662 +3 7414 1874 110 +3 5858 5352 5814 +3 6329 4106 7415 +3 1878 7417 1756 +3 7417 1878 2515 +3 7366 7324 7130 +3 7419 7398 1753 +3 7189 7188 7420 +3 5018 5144 7422 +3 7175 7389 7424 +3 7423 7422 7424 +3 6580 3638 605 +3 7045 7157 284 +3 129 2300 1553 +3 7432 7430 284 +3 1872 5689 1340 +3 3307 7006 7433 +3 2015 3779 1063 +3 5673 5168 7434 +3 6795 3121 4341 +3 2795 1879 2852 +3 4804 934 3343 +3 2184 2920 3591 +3 7050 1882 7439 +3 5316 1916 2049 +3 7439 1882 7342 +3 110 2227 2851 +3 2852 2854 2795 +3 126 832 2035 +3 2852 1886 7439 +3 7439 1886 7050 +3 2455 5695 2595 +3 5672 6143 7440 +3 7440 4518 5672 +3 6720 6718 7445 +3 7444 1889 7445 +3 7445 1889 61 +3 7373 7375 7446 +3 1893 1890 7446 +3 2963 1153 5825 +3 5054 2187 1033 +3 1893 1892 7447 +3 1153 2963 7228 +3 7447 1892 3600 +3 1715 1639 5215 +3 6810 6809 7448 +3 3578 6460 6462 +3 3916 2829 800 +3 7508 1891 3346 +3 3400 5371 1332 +3 2427 6861 2566 +3 5604 1914 5046 +3 7121 7123 7451 +3 7449 7448 7451 +3 7416 5807 7452 +3 6127 2449 2778 +3 7452 1898 7416 +3 99 2675 7453 +3 2857 7453 252 +3 2857 1898 7452 +3 2449 4708 2778 +3 7452 7455 2857 +3 2856 1982 7455 +3 7261 5334 7456 +3 7459 740 3595 +3 250 2491 7459 +3 2676 7460 2872 +3 2117 3280 3727 +3 513 2885 3297 +3 2676 1899 7461 +3 7461 1899 6400 +3 7461 1901 7460 +3 5140 7462 5788 +3 2227 559 1955 +3 7462 1905 1144 +3 3688 2957 7463 +3 7463 1905 3258 +3 3421 3258 7465 +3 7465 1905 7462 +3 2368 6976 7468 +3 7467 3962 7468 +3 7469 196 7185 +3 2493 7159 4067 +3 6636 6018 1253 +3 7467 7469 2814 +3 3242 2477 3815 +3 7007 2247 3902 +3 5751 7330 7474 +3 7120 7118 7477 +3 7474 7472 7477 +3 7478 231 5917 +3 5150 7259 7479 +3 6146 6989 7481 +3 2049 7426 5316 +3 5039 3904 4986 +3 7480 7479 7481 +3 7144 7142 7482 +3 6666 6669 7483 +3 1909 2461 7485 +3 1910 1909 7485 +3 5030 5033 249 +3 1910 3656 1972 +3 2487 7043 4060 +3 5850 5428 7486 +3 3656 1910 7486 +3 7486 1910 7485 +3 7329 7423 7488 +3 3856 3855 7490 +3 6129 6139 7491 +3 6349 1913 259 +3 259 7492 6349 +3 7491 7490 7492 +3 1810 5991 6004 +3 5019 5020 1009 +3 7495 1920 127 +3 1699 474 2891 +3 7496 1920 2303 +3 1919 7497 7278 +3 7092 436 2741 +3 5050 3991 2566 +3 7497 1920 7495 +3 7499 7167 1858 +3 1922 7502 2866 +3 1922 7499 1923 +3 1691 3175 735 +3 6618 6977 2584 +3 1923 7502 1922 +3 2373 6882 6879 +3 7502 1923 911 +3 1928 1925 1933 +3 1933 1925 6642 +3 1928 1926 7504 +3 627 7324 425 +3 1180 7257 5014 +3 1926 1928 7505 +3 7332 6621 4339 +3 6654 1930 7283 +3 7283 1930 5344 +3 1852 4067 7159 +3 7438 6233 7197 +3 316 1931 7197 +3 7197 1931 2028 +3 5044 1932 6150 +3 6150 2095 7078 +3 199 6233 262 +3 1836 1933 6642 +3 7077 6642 1925 +3 847 2807 2486 +3 4722 6225 6606 +3 1936 5485 6606 +3 3902 2247 2597 +3 3554 2427 2380 +3 2380 1449 1696 +3 163 7500 1158 +3 1113 2280 2646 +3 2646 2280 53 +3 5485 1936 6282 +3 5906 5320 5073 +3 7053 2742 5012 +3 1084 6008 1085 +3 1940 1759 6008 +3 2671 2697 1743 +3 820 5011 2401 +3 5754 6008 5091 +3 5763 1941 6922 +3 6922 1941 7170 +3 7466 6701 6871 +3 1743 2835 2671 +3 2840 6090 819 +3 1286 5167 6837 +3 6871 6922 6837 +3 6700 3159 6842 +3 495 7166 6641 +3 1942 5834 50 +3 5927 1943 771 +3 1943 6514 1474 +3 2480 4793 388 +3 3833 3831 2004 +3 2987 3869 5425 +3 5124 281 2272 +3 4928 3783 1034 +3 2680 3055 5455 +3 2475 6300 5398 +3 596 4422 6042 +3 4928 5124 4422 +3 2701 2514 5938 +3 7319 2925 4272 +3 7321 6250 6738 +3 5290 4722 4035 +3 7377 7379 3883 +3 7400 4160 4159 +3 4159 3883 7400 +3 4145 4144 1949 +3 4224 1947 3807 +3 5618 5616 3940 +3 1599 1590 734 +3 1947 3105 1949 +3 4820 4216 4211 +3 3781 1948 3807 +3 3807 1948 5701 +3 3807 1949 3781 +3 7435 1950 3937 +3 4427 4999 4998 +3 5215 6437 2075 +3 4998 327 4427 +3 7313 1951 640 +3 1952 7298 2422 +3 7298 1952 1020 +3 7428 4447 6165 +3 7313 7435 7298 +3 5900 7052 7241 +3 2095 2870 7147 +3 2869 1953 7147 +3 7017 7317 7145 +3 6653 6641 7014 +3 7014 7145 6935 +3 6774 3530 6726 +3 4990 4992 3462 +3 6423 3422 5893 +3 4809 4808 6571 +3 5517 5516 6495 +3 6571 6726 6495 +3 6464 5139 2851 +3 1955 5883 2871 +3 6758 2505 1946 +3 1958 6464 6214 +3 217 377 7525 +3 6464 1958 5139 +3 7525 377 4201 +3 3479 1132 6052 +3 3202 1810 5781 +3 5820 5884 6181 +3 7229 5423 2934 +3 2308 940 6134 +3 637 5043 1819 +3 1960 6341 1958 +3 1958 6214 1960 +3 5893 3560 1410 +3 7420 1553 1355 +3 2835 7305 2689 +3 1992 1967 5647 +3 2467 5472 4197 +3 6940 3116 1575 +3 5389 1971 2879 +3 52 1970 5389 +3 6244 3995 5203 +3 5174 6530 5103 +3 6918 6919 5060 +3 5103 5203 5060 +3 1975 1974 2880 +3 6767 6296 959 +3 2880 1974 5394 +3 940 2308 53 +3 6958 6920 4935 +3 7296 6995 4915 +3 7241 7182 4824 +3 4915 4935 4824 +3 2671 2318 6897 +3 2397 5508 6423 +3 1975 4691 7400 +3 3740 4720 6093 +3 2880 4691 1975 +3 7076 7306 4740 +3 3679 615 652 +3 615 3679 7457 +3 6882 3179 6879 +3 5918 2528 5320 +3 7396 1978 4654 +3 4740 1979 4654 +3 4626 4680 6268 +3 1979 4772 1980 +3 1980 4654 1979 +3 4654 1980 7396 +3 7455 1982 4531 +3 4531 1982 1687 +3 5710 2456 2525 +3 101 2710 4451 +3 1983 4390 1986 +3 4390 1983 7101 +3 1984 4390 2882 +3 4390 1984 4531 +3 4531 1986 4390 +3 1986 7100 1983 +3 4294 1058 5285 +3 6275 5480 2311 +3 1988 2814 4287 +3 4983 6434 233 +3 4382 1988 4287 +3 2814 1988 3962 +3 7331 7333 4056 +3 2064 1417 362 +3 6146 5014 3890 +3 4056 4186 3890 +3 335 2659 5052 +3 7064 1990 3841 +3 4327 6898 3741 +3 1990 6979 2884 +3 3841 1994 2799 +3 5275 2926 5320 +3 52 2577 1965 +3 7249 3812 2884 +3 6547 5679 2926 +3 1994 3812 117 +3 3812 1994 3841 +3 3396 4977 3380 +3 6897 2318 2280 +3 1964 1995 7038 +3 7038 6800 5518 +3 6800 5831 1998 +3 5683 5340 4973 +3 2398 681 6651 +3 1998 5518 6800 +3 5518 1998 5277 +3 5404 5405 7264 +3 4971 2810 1460 +3 2847 468 1929 +3 4720 7127 6093 +3 6992 6991 7503 +3 3202 2887 4443 +3 5991 3202 4443 +3 2939 5175 7493 +3 7503 7264 7493 +3 7223 7221 7471 +3 7442 1999 1823 +3 132 7025 2599 +3 7442 7471 7421 +3 3282 3220 7418 +3 6271 6272 7369 +3 7143 6132 5547 +3 2070 3185 7348 +3 7369 7418 7348 +3 5025 5224 4968 +3 3000 2007 7302 +3 7392 2001 7294 +3 5431 2004 7272 +3 2004 5425 2886 +3 2618 6949 2916 +3 7294 2006 7272 +3 7272 2006 7302 +3 6463 6549 307 +3 7302 2007 5431 +3 5431 7272 7302 +3 1499 3055 2931 +3 7242 6913 6103 +3 2428 7324 7366 +3 2794 3545 5602 +3 6391 1253 6018 +3 5623 3048 2116 +3 1037 2333 291 +3 3032 3057 7237 +3 4838 3452 6816 +3 3635 2013 7222 +3 7222 2013 382 +3 5724 5056 5997 +3 7222 7237 119 +3 7218 2031 2719 +3 4651 3913 7224 +3 7396 2014 7205 +3 2031 2846 7205 +3 2122 6399 1635 +3 5071 2015 7174 +3 1864 3179 366 +3 7174 2015 5601 +3 7174 2017 2261 +3 1817 3015 7140 +3 2017 2888 7140 +3 7086 812 5552 +3 4672 6431 6432 +3 4962 4963 479 +3 2644 4959 2482 +3 2888 2017 7122 +3 7122 2017 7174 +3 7122 2018 290 +3 2602 1011 5568 +3 2611 1012 1902 +3 6118 4803 6064 +3 7116 2019 7113 +3 292 4225 3571 +3 7113 2019 4755 +3 6816 3450 4838 +3 2019 5834 2324 +3 2019 7116 7091 +3 5469 5577 1402 +3 7065 2020 2844 +3 7501 6944 7060 +3 7062 7065 7060 +3 5230 5229 7035 +3 6204 6205 7030 +3 7192 5774 6952 +3 5468 6216 6950 +3 6952 7011 6950 +3 4093 4009 3240 +3 1140 1060 5892 +3 315 6923 2727 +3 776 5690 5399 +3 1977 576 6840 +3 6896 6923 6840 +3 6832 6833 6815 +3 1431 2942 6724 +3 2025 2023 6708 +3 6708 2023 3827 +3 2024 6708 2892 +3 6708 2024 6747 +3 6747 2025 6708 +3 7333 5822 6665 +3 924 2026 6657 +3 7498 204 1233 +3 6657 2026 2874 +3 3280 2346 6858 +3 6665 6702 6657 +3 7283 2028 1931 +3 1931 6654 7283 +3 6954 6917 6617 +3 3501 2029 6609 +3 2576 2254 6609 +3 1849 4944 4448 +3 6124 4001 5703 +3 6589 5835 5531 +3 7031 2030 6575 +3 2461 208 1182 +3 6575 2030 1625 +3 6555 2031 7205 +3 6586 6555 4375 +3 5023 3996 1463 +3 6513 2874 2026 +3 7116 2032 2034 +3 2829 3916 4016 +3 6702 6402 6506 +3 2034 924 6506 +3 2034 2032 6442 +3 7028 7312 6429 +3 4940 4941 3195 +3 6406 434 325 +3 6220 5356 6347 +3 2036 98 6347 +3 6339 6513 2026 +3 2705 4029 3150 +3 1486 484 425 +3 6339 2036 152 +3 6843 5448 2459 +3 5032 1551 2164 +3 876 6429 6338 +3 6338 2036 6347 +3 5718 5717 6327 +3 7434 6935 6277 +3 6310 6327 6277 +3 7250 7260 6246 +3 6158 6159 6210 +3 7458 6809 2350 +3 6147 6210 1739 +3 398 2037 2923 +3 766 2457 6732 +3 2923 6109 398 +3 1694 1430 3126 +3 6622 3039 6105 +3 6485 6484 6056 +3 2415 2454 3180 +3 6105 6109 6056 +3 2889 1799 3363 +3 5370 5369 6022 +3 7443 7062 6011 +3 6022 6053 6011 +3 2038 7008 5966 +3 5882 7054 28 +3 757 2699 1685 +3 2311 3631 6275 +3 3422 7473 4956 +3 2039 5882 5966 +3 3193 6637 4117 +3 5882 2039 2040 +3 5819 3176 131 +3 5882 2040 7054 +3 4927 2424 414 +3 1343 6390 5652 +3 755 2125 3592 +3 947 1726 2769 +3 2041 5812 2043 +3 4735 4267 5812 +3 991 2042 5812 +3 2042 5859 2043 +3 2043 5812 2042 +3 2525 3285 5710 +3 2043 4736 2041 +3 1331 5231 705 +3 5108 423 2156 +3 5602 4797 1993 +3 3983 1911 3607 +3 2931 4421 1499 +3 4508 3771 3191 +3 2265 7353 3729 +3 1879 2047 5787 +3 1516 5785 5706 +3 6905 4919 4132 +3 56 2071 5765 +3 1659 444 3140 +3 5785 5787 5765 +3 7504 7101 5727 +3 5627 5270 485 +3 5041 4914 4634 +3 7328 6722 5719 +3 5727 5756 5719 +3 7326 7323 5700 +3 6933 7373 5698 +3 2452 4774 6557 +3 2789 4909 1927 +3 4671 2050 5678 +3 5678 2050 5661 +3 2078 3447 6832 +3 5678 2074 4671 +3 5671 2074 1 +3 1742 5894 7382 +3 1599 4562 6914 +3 2053 5647 1967 +3 7382 2058 5593 +3 4909 1434 2711 +3 5593 2058 5666 +3 366 3179 3183 +3 5593 2059 7382 +3 5593 2053 2059 +3 4903 4904 5102 +3 2066 6302 5590 +3 1751 1730 1727 +3 4900 4901 3739 +3 5562 3771 6794 +3 2066 1111 5562 +3 5549 3072 169 +3 2066 5549 169 +3 5549 2066 5590 +3 5475 7032 3717 +3 2067 6681 5513 +3 5477 3393 2164 +3 5284 5920 3867 +3 2067 718 5477 +3 2467 2067 5513 +3 5513 5434 2467 +3 6505 7410 5994 +3 4760 4756 5375 +3 115 5375 465 +3 2071 5327 2866 +3 7027 7026 5318 +3 5327 5344 5318 +3 2072 5294 2076 +3 5294 2072 6604 +3 2076 6605 2072 +3 2076 7367 5285 +3 5274 2074 5678 +3 2900 2076 5294 +3 5294 5274 2900 +3 5571 6117 5270 +3 4723 5179 2928 +3 490 5248 4377 +3 1560 113 6579 +3 5869 2151 5248 +3 2078 5247 2080 +3 5247 2078 6815 +3 3737 2080 5247 +3 2080 4907 2078 +3 1726 947 6697 +3 6994 3940 3102 +3 3050 2042 991 +3 274 5136 1455 +3 4889 1381 737 +3 5121 2084 2956 +3 7255 1212 1770 +3 3559 2688 3601 +3 5153 5121 1278 +3 4877 4878 2218 +3 5180 5546 4143 +3 2771 2569 736 +3 5242 2087 5069 +3 2087 731 5095 +3 5069 5095 14 +3 4816 2088 954 +3 954 5055 4816 +3 6608 4225 292 +3 6094 1270 4874 +3 3928 3658 4357 +3 4639 4234 4972 +3 6095 4889 4911 +3 4906 1456 4040 +3 4906 4911 1411 +3 6142 4872 737 +3 4439 2089 4883 +3 1585 6902 1275 +3 3202 5991 1810 +3 4883 2093 4439 +3 2090 4871 4185 +3 2093 481 4871 +3 5462 3118 2508 +3 33 2330 2093 +3 4616 2102 2077 +3 840 3288 2083 +3 4049 5729 4869 +3 3509 2389 6505 +3 33 2093 4883 +3 4581 3076 2927 +3 4860 4862 341 +3 7100 7265 1194 +3 7472 5756 4825 +3 6500 6410 4802 +3 4825 4870 4802 +3 1778 1779 2856 +3 4205 898 5804 +3 6310 7315 4794 +3 7047 2094 1109 +3 1109 4778 7047 +3 111 1932 4729 +3 2097 4729 2905 +3 4729 2097 4794 +3 4729 4794 3790 +3 7064 7063 4728 +3 7443 2906 4693 +3 5166 2587 1801 +3 6200 4280 460 +3 798 1568 206 +3 4432 7018 6005 +3 2887 930 2555 +3 2099 4687 2906 +3 6049 864 866 +3 4687 2099 4728 +3 4674 6586 265 +3 4674 2100 2719 +3 6053 7218 4644 +3 3183 2447 366 +3 4644 2100 2099 +3 2105 2101 5142 +3 5142 4595 2105 +3 721 3584 935 +3 2101 2105 44 +3 4616 2105 1493 +3 242 443 2490 +3 1751 1727 2790 +3 4594 5681 5392 +3 4594 3033 5113 +3 4578 2225 1316 +3 4578 4550 858 +3 4578 2109 3328 +3 1993 4797 2981 +3 4550 2111 858 +3 4550 4578 1316 +3 4491 2114 6114 +3 2116 4483 2159 +3 4491 4517 4483 +3 5657 6094 1271 +3 7277 7276 4469 +3 5500 2123 4469 +3 6900 2119 2911 +3 4425 2120 4455 +3 4455 2120 2773 +3 1762 2122 4425 +3 4455 2123 4425 +3 5113 3033 157 +3 3925 2124 4413 +3 2124 6213 2912 +3 5535 1586 2445 +3 4413 2126 3925 +3 1282 4393 157 +3 6505 2389 7410 +3 4393 2126 753 +3 4389 2126 4413 +3 2127 2558 4380 +3 1770 6326 7255 +3 4845 4846 1488 +3 2433 3104 4936 +3 6096 2845 4283 +3 4213 4727 4359 +3 4359 4374 4380 +3 7483 7482 4355 +3 5342 7397 4319 +3 4343 4355 4319 +3 7487 7488 4316 +3 6617 6654 4282 +3 4843 311 1298 +3 7389 7391 4269 +3 12 4316 4269 +3 4401 1876 2121 +3 5959 5064 4214 +3 2128 4214 5064 +3 3777 2931 2680 +3 4559 471 1729 +3 2129 4180 2130 +3 4180 2129 6577 +3 4161 2130 4180 +3 2130 3958 2129 +3 3104 2433 3466 +3 4180 4214 2128 +3 2128 4161 4180 +3 469 1623 4882 +3 7182 2132 4150 +3 2132 1143 4135 +3 2443 2512 6005 +3 2133 4135 5451 +3 4135 2133 4150 +3 1890 7447 4118 +3 4118 2134 1890 +3 2742 7053 4918 +3 3213 5396 7146 +3 5700 5698 4116 +3 2134 2915 4116 +3 2134 4118 4112 +3 2434 1865 6680 +3 4112 2915 2134 +3 2914 5176 3222 +3 5200 5197 4081 +3 2628 2579 1059 +3 7030 7035 4004 +3 4041 4081 4004 +3 4109 4268 4003 +3 2940 6380 2192 +3 3373 2136 320 +3 320 3999 3373 +3 5088 77 3664 +3 4145 3008 3990 +3 3999 4003 3990 +3 7011 5218 3932 +3 5854 5187 3926 +3 3932 3979 3926 +3 7411 7408 3923 +3 4343 7208 3900 +3 2639 2335 455 +3 7480 6666 3891 +3 3900 3923 3891 +3 2443 5617 6872 +3 6727 2139 2145 +3 6856 2140 3838 +3 2140 6859 2342 +3 3837 2142 3838 +3 3727 5976 2573 +3 3838 2142 6856 +3 4250 3221 2142 +3 3838 2145 3837 +3 3837 2145 2139 +3 4982 5055 3834 +3 3784 5852 3036 +3 4894 5426 2492 +3 1638 4762 5707 +3 6846 2676 4630 +3 569 2146 3763 +3 3763 2146 2347 +3 3763 3784 1251 +3 6328 2147 3750 +3 3750 2147 6325 +3 3505 3280 2117 +3 2152 3750 2685 +3 2149 2148 3743 +3 4076 4159 7514 +3 3737 2149 3743 +3 3108 5615 4260 +3 3690 4225 3590 +3 5247 2151 2149 +3 2800 3802 1210 +3 7514 2916 4163 +3 3737 3743 2918 +3 3853 2154 7083 +3 4826 4827 4745 +3 6662 2158 2923 +3 2923 2158 6109 +3 153 521 2189 +3 2393 3606 775 +3 765 7149 3934 +3 2159 419 2116 +3 2942 7016 5653 +3 2942 1652 6724 +3 2943 1803 128 +3 3978 2354 2960 +3 551 5584 5971 +3 2165 2976 379 +3 2895 5999 3504 +3 6649 4272 2925 +3 2166 3938 142 +3 871 6456 4823 +3 2167 4156 4142 +3 3011 4167 1502 +3 3011 2168 6285 +3 711 360 1170 +3 1611 3015 6870 +3 3015 2170 7140 +3 978 7242 5379 +3 811 5105 2054 +3 153 4633 5259 +3 3033 2171 1282 +3 3339 827 3043 +3 161 5193 2208 +3 2173 3598 167 +3 5861 2174 4504 +3 6872 2512 2443 +3 704 5240 368 +3 4753 3709 2981 +3 209 3054 3273 +3 3072 2177 34 +3 34 2177 5084 +3 3242 1391 2180 +3 3203 2182 281 +3 2663 6461 612 +3 5158 1561 1140 +3 378 6556 2646 +3 366 3150 1864 +3 7220 3281 6483 +3 3586 1208 5599 +3 57 5261 2990 +3 3535 1477 2970 +3 2189 3119 153 +3 759 3106 4933 +3 3106 2185 5813 +3 3267 2188 558 +3 5680 2191 3130 +3 3130 2191 2702 +3 37 838 4752 +3 2666 5511 2271 +3 2192 1382 2940 +3 5473 3131 5471 +3 38 206 1568 +3 2194 6762 1677 +3 2741 1449 2380 +3 2195 3132 122 +3 6196 2474 2439 +3 1578 6776 504 +3 5372 6558 3141 +3 1963 3434 7129 +3 5213 2198 3143 +3 39 186 6195 +3 1976 712 5568 +3 5409 6265 2455 +3 5409 2252 6265 +3 471 4092 7139 +3 3281 127 7496 +3 2696 6086 614 +3 2639 2474 2770 +3 2203 347 348 +3 347 2203 3861 +3 1497 5680 3130 +3 1497 2580 6582 +3 2207 236 1399 +3 1568 3480 182 +3 3375 1544 227 +3 4200 426 2220 +3 4432 2574 7018 +3 6668 7242 6103 +3 2220 211 4200 +3 2208 6468 342 +3 4662 2414 3229 +3 4812 6571 4808 +3 7378 1957 1212 +3 6679 6752 1929 +3 2419 6 2159 +3 5592 2211 364 +3 2573 7508 5985 +3 7378 7255 1452 +3 1710 3675 5000 +3 5732 2213 1372 +3 1907 4067 2746 +3 1568 182 38 +3 3842 4875 306 +3 5110 4829 4806 +3 1743 3066 2812 +3 5281 6692 3314 +3 1489 1301 3197 +3 6569 2216 2726 +3 4048 1745 2578 +3 207 2217 675 +3 3054 2219 3273 +3 3304 464 2826 +3 3974 5143 2431 +3 2222 216 506 +3 2222 3292 215 +3 7459 2491 7456 +3 7255 4216 1452 +3 3102 3940 5616 +3 2223 1239 1044 +3 579 3319 219 +3 43 220 6062 +3 3328 2225 4578 +3 2524 3436 5524 +3 4568 6632 5895 +3 3669 2287 552 +3 7039 3172 5165 +3 3749 511 5810 +3 5482 223 3349 +3 5644 2230 3362 +3 3362 2230 1476 +3 4255 2231 3373 +3 4108 2232 1127 +3 369 4001 5317 +3 4119 2234 1346 +3 2234 976 3697 +3 4161 232 59 +3 891 3412 5210 +3 2621 3304 2826 +3 7320 1690 3983 +3 2430 6138 1304 +3 687 2007 5081 +3 1580 3433 6784 +3 5619 2883 6165 +3 4323 239 3433 +3 5548 243 67 +3 5691 2240 3437 +3 2240 6075 282 +3 3370 1240 2612 +3 6373 1991 1765 +3 634 2243 4714 +3 246 6741 410 +3 1991 4169 1765 +3 248 5782 178 +3 5135 886 6426 +3 683 1644 4052 +3 3472 248 0 +3 3148 7043 4244 +3 1961 4468 1971 +3 467 2248 4356 +3 4665 6527 4791 +3 2248 4453 396 +3 6896 2021 2253 +3 2253 5358 549 +3 6609 2254 3501 +3 4960 5709 788 +3 1595 54 6831 +3 57 269 5261 +3 3621 270 58 +3 2622 5083 4789 +3 5599 4087 3586 +3 1613 138 5931 +3 1455 3550 274 +3 272 4782 4539 +3 4539 3555 272 +3 3508 2267 3986 +3 1458 4926 6493 +3 3126 5276 1694 +3 1262 2337 4339 +3 7437 4579 6965 +3 3583 4677 4749 +3 7267 6101 4782 +3 3583 2271 6812 +3 6608 4780 130 +3 2272 525 5124 +3 2273 2275 5970 +3 741 285 7444 +3 5570 290 3613 +3 2607 3870 1730 +3 2283 7122 290 +3 1548 3680 3338 +3 3245 4468 1961 +3 5842 2284 3630 +3 7222 2286 3635 +3 3635 2286 6433 +3 4040 6876 4906 +3 3648 2287 4970 +3 4607 2288 585 +3 2288 3678 304 +3 864 6282 7372 +3 2289 3712 2291 +3 3715 2291 3712 +3 2932 1481 1453 +3 1453 5740 1114 +3 3794 6103 6913 +3 3661 2980 1972 +3 1972 2980 5269 +3 956 4776 4779 +3 668 4773 4593 +3 2294 618 4686 +3 3304 4518 3042 +3 3396 4976 3063 +3 5178 4897 4771 +3 2277 317 4193 +3 1189 6065 5933 +3 3372 3845 340 +3 5747 3811 3744 +3 2563 3386 5061 +3 5853 2804 7082 +3 3787 2304 3789 +3 2305 3792 2538 +3 2334 1473 1908 +3 2595 2845 5409 +3 329 2306 40 +3 2306 3811 330 +3 4401 5383 310 +3 7456 2491 3813 +3 5383 2309 310 +3 4029 2720 5171 +3 3602 2892 3827 +3 6795 2980 3121 +3 6055 2312 3840 +3 6320 1712 3453 +3 5488 5501 5531 +3 6218 2313 6474 +3 7083 2315 3853 +3 4726 3859 345 +3 4563 2317 3864 +3 2548 3909 357 +3 3912 2726 2216 +3 3912 7155 5280 +3 3936 3762 4979 +3 3936 3559 3762 +3 6480 2319 3937 +3 4212 7008 4761 +3 6461 3870 612 +3 3937 2319 7435 +3 818 3943 5007 +3 2158 300 6056 +3 4246 2321 4717 +3 4863 6553 1734 +3 7437 5563 2388 +3 5715 3762 3601 +3 5951 878 1198 +3 4151 5196 4353 +3 3878 1115 4006 +3 5490 1023 3974 +3 3306 2405 4017 +3 2569 4303 5599 +3 5375 4756 2520 +3 390 2326 4039 +3 4039 2326 5252 +3 7004 1918 1556 +3 843 7111 5097 +3 5628 7227 2534 +3 5013 2327 4071 +3 2327 1594 1311 +3 4078 4219 2975 +3 1127 2328 4108 +3 4108 2328 7106 +3 67 399 5548 +3 7270 2537 5978 +3 4559 4092 471 +3 733 5106 471 +3 4360 1045 557 +3 1473 2334 663 +3 523 2336 4139 +3 2812 3066 1908 +3 2339 566 406 +3 2339 3344 4154 +3 2340 562 397 +3 5649 1572 6770 +3 413 6078 2640 +3 3682 3376 6394 +3 6355 6899 945 +3 3684 4776 4744 +3 4171 3420 4273 +3 3865 7130 7136 +3 655 2422 1193 +3 3399 6411 4751 +3 7368 1056 866 +3 4163 6949 6153 +3 6887 2352 4195 +3 4195 2352 4493 +3 5599 2746 4087 +3 4195 4493 4492 +3 4267 4735 4079 +3 7310 2353 4207 +3 4207 2353 2395 +3 2092 2355 4969 +3 430 2356 4217 +3 4217 433 430 +3 439 2357 4243 +3 2357 4242 440 +3 442 23 2360 +3 3373 2361 4255 +3 2230 1075 2940 +3 780 4732 2008 +3 452 6499 6383 +3 3697 6375 4276 +3 230 4277 459 +3 4049 4869 645 +3 1041 4277 5267 +3 6808 1215 2757 +3 86 2365 4292 +3 4292 2365 7343 +3 4663 7177 4307 +3 2507 462 1541 +3 6876 4040 4702 +3 3853 2315 6825 +3 4948 2367 4329 +3 4329 2367 6694 +3 2368 7468 2369 +3 2369 4347 2368 +3 7061 2371 4347 +3 2374 4357 299 +3 970 4358 5354 +3 5845 2375 4370 +3 4370 2375 4368 +3 3369 1141 4371 +3 1217 4373 5988 +3 2110 1491 47 +3 490 482 2984 +3 1551 5032 6336 +3 7136 5504 3865 +3 5408 2378 4378 +3 4722 5485 3218 +3 4732 2382 266 +3 640 6130 1950 +3 5663 7226 4718 +3 2003 2790 5589 +3 5978 7385 7270 +3 1437 504 1579 +3 4412 5071 255 +3 1738 510 6407 +3 7322 4360 5040 +3 4430 5944 3320 +3 2387 4437 519 +3 4437 2387 6174 +3 3652 3803 1816 +3 5112 4458 528 +3 4326 3473 1019 +3 1412 3427 1424 +3 3317 7137 4713 +3 40 2390 4465 +3 2416 1651 6443 +3 2390 4700 604 +3 5211 356 5819 +3 2391 4467 4955 +3 6591 1504 2392 +3 2392 4482 4703 +3 4207 2395 4492 +3 4700 4706 487 +3 4492 2395 4195 +3 7494 543 4493 +3 7349 2396 4504 +3 3310 3772 6115 +3 2827 7300 1814 +3 441 5620 681 +3 2006 2415 3180 +3 3212 3009 1489 +3 4695 4696 5640 +3 1546 1995 4867 +3 3465 2400 554 +3 2423 7303 381 +3 7084 1966 7074 +3 7379 2551 3342 +3 7211 2534 7227 +3 560 6793 2344 +3 6420 36 1416 +3 4541 2401 5011 +3 5101 774 2460 +3 571 2402 4563 +3 1744 5922 5762 +3 3147 2526 4574 +3 2403 4592 575 +3 4592 2403 1081 +3 2404 4606 581 +3 2404 4605 582 +3 4017 2405 4609 +3 4609 2405 4608 +3 1868 4615 2849 +3 7061 7340 1835 +3 1388 4627 6386 +3 4627 2407 4629 +3 2408 4629 597 +3 2054 6250 7321 +3 625 4692 5982 +3 2410 4661 605 +3 4661 2410 4858 +3 42 607 643 +3 4663 607 4664 +3 1296 609 6195 +3 4667 2411 4666 +3 938 1704 3102 +3 5420 4682 3228 +3 4753 4797 1452 +3 6273 6394 3211 +3 3229 2414 4689 +3 5181 319 5027 +3 4689 2414 624 +3 4228 2551 5047 +3 1704 1903 6994 +3 4931 2415 2001 +3 2001 2415 7294 +3 1649 2416 4710 +3 4710 2416 5915 +3 2413 4685 4684 +3 2417 1951 460 +3 2363 5814 3985 +3 4725 2110 1493 +3 3090 725 4896 +3 1856 1707 3819 +3 3934 7149 3929 +3 2422 655 1952 +3 37 4752 4747 +3 7303 657 4752 +3 666 2425 668 +3 2425 4775 673 +3 2758 594 6052 +3 1718 6132 7143 +3 2426 683 682 +3 683 2426 1644 +3 3992 1738 7176 +3 1192 2429 4800 +3 2430 4801 688 +3 4801 2430 6074 +3 1221 3629 1467 +3 4007 2431 4805 +3 5006 2637 4813 +3 937 4816 5266 +3 6309 1359 5028 +3 5088 2432 77 +3 6265 6305 2995 +3 705 77 2432 +3 7383 4832 1804 +3 2258 2564 7155 +3 4832 2434 6681 +3 4406 4619 4683 +3 1488 4846 1544 +3 7115 943 6587 +3 2784 3889 2941 +3 6882 2373 4993 +3 3253 3998 4406 +3 6877 2437 4851 +3 7000 2493 4836 +3 4976 3396 3706 +3 4333 5066 992 +3 716 2440 4856 +3 4837 5022 5078 +3 6805 2442 2445 +3 3365 2445 78 +3 3600 5533 3012 +3 2102 4616 47 +3 6570 2446 1270 +3 2448 4888 735 +3 4888 2448 4890 +3 497 4896 4893 +3 742 2450 4897 +3 4677 4678 4749 +3 4912 4937 764 +3 4504 2600 5861 +3 2125 4923 4389 +3 6581 5295 4676 +3 2001 2453 4931 +3 3106 2454 4933 +3 4934 760 83 +3 763 2457 4937 +3 1315 2603 2505 +3 1183 767 2614 +3 6470 1087 1802 +3 773 5839 245 +3 2479 6857 5617 +3 4943 1463 3996 +3 7485 2461 1179 +3 1179 2461 5921 +3 7043 3148 4060 +3 4948 4329 777 +3 780 6401 4952 +3 4732 780 4951 +3 4952 784 4951 +3 4672 6432 3446 +3 648 4576 2570 +3 788 2466 4960 +3 4960 2466 5937 +3 5684 3570 4424 +3 6792 4376 7085 +3 5929 796 86 +3 3628 6038 6957 +3 7428 6165 92 +3 4202 6270 6974 +3 3018 2998 2623 +3 934 4804 3761 +3 3509 3345 2959 +3 1654 3515 4346 +3 7087 960 1268 +3 92 6763 1797 +3 6897 2663 2578 +3 648 2570 6470 +3 5933 2475 5002 +3 2475 5399 814 +3 7080 2683 5003 +3 2922 5006 4813 +3 6857 2479 5006 +3 3943 2480 5007 +3 1208 3586 1079 +3 5007 2480 7478 +3 819 3984 2840 +3 5628 2485 5009 +3 5009 2485 6539 +3 2486 5013 4071 +3 5013 2486 2807 +3 1674 5987 4910 +3 5846 919 5251 +3 5233 2487 5028 +3 5028 2487 7387 +3 4914 5041 5036 +3 3339 2226 5051 +3 830 194 2489 +3 4899 2566 156 +3 5058 2489 5063 +3 1079 3586 3441 +3 7425 1090 3236 +3 6116 2878 6902 +3 5837 3659 5082 +3 7236 2554 7206 +3 2836 2952 629 +3 5088 3265 3122 +3 3122 2560 5088 +3 7111 2494 5097 +3 5097 2494 7363 +3 5101 2497 5105 +3 4072 3681 3696 +3 2499 5111 850 +3 5111 2499 5114 +3 4352 2500 5128 +3 3468 2625 5131 +3 5128 2500 5132 +3 1122 5170 875 +3 298 4667 4666 +3 1468 5171 6507 +3 60 3723 1142 +3 5195 5634 1514 +3 1324 3025 2109 +3 5195 2501 5196 +3 4151 885 5196 +3 2503 5212 892 +3 3143 2504 5213 +3 1444 2248 467 +3 4187 2505 2412 +3 900 6381 649 +3 5245 1716 2507 +3 4624 3723 242 +3 2508 914 2938 +3 4727 5918 5906 +3 2075 7178 6901 +3 914 4348 910 +3 3992 2509 5251 +3 2496 1087 3384 +3 4820 4753 1452 +3 4433 3591 2921 +3 2513 5256 927 +3 4630 2872 1607 +3 5256 2513 324 +3 939 836 4669 +3 3591 7470 1121 +3 5221 5940 6284 +3 2410 3584 721 +3 941 5526 3316 +3 663 2721 6516 +3 351 5304 951 +3 2516 5380 953 +3 3358 961 5313 +3 5949 5435 4658 +3 5507 3730 4633 +3 2347 2518 3763 +3 2148 5322 3743 +3 5856 2523 5329 +3 5329 2523 5328 +3 4574 2526 5333 +3 7269 1624 1780 +3 4478 5345 968 +3 487 7161 4653 +3 5345 4478 7291 +3 1122 4647 880 +3 212 1821 2657 +3 2529 5361 974 +3 6016 4326 6019 +3 3587 1511 2420 +3 5361 2529 5360 +3 5935 4381 4967 +3 6817 2544 1534 +3 2554 4739 7208 +3 769 4354 5159 +3 5249 4887 6903 +3 6603 2309 91 +3 1104 4283 3096 +3 2535 5390 984 +3 5400 5686 1096 +3 2535 984 990 +3 2443 2617 2479 +3 3964 4050 2749 +3 972 5818 1690 +3 2112 2678 1847 +3 5851 2539 5419 +3 6043 5817 4642 +3 5419 2539 5422 +3 91 995 6603 +3 5429 2532 792 +3 4672 3594 6431 +3 2541 5759 1126 +3 2081 5447 1006 +3 1717 2543 2273 +3 3144 3444 6284 +3 5463 2543 5465 +3 1016 5909 5471 +3 3096 3290 5597 +3 2821 3228 7010 +3 6874 942 4306 +3 3341 2054 7321 +3 5490 2545 5489 +3 3909 2548 5512 +3 4050 3964 1119 +3 5969 2550 5522 +3 2550 5520 1030 +3 331 1036 3979 +3 2558 93 2913 +3 3334 7301 5087 +3 2559 6457 1438 +3 5663 4718 4638 +3 2749 4414 3964 +3 5171 2560 3122 +3 2082 6453 4636 +3 2561 1276 2223 +3 2562 5566 3888 +3 5566 2562 5569 +3 1809 4470 5572 +3 2889 2565 5591 +3 1054 2568 5592 +3 3376 3682 5527 +3 867 2575 1068 +3 3965 1062 5596 +3 7357 2572 1843 +3 1843 2572 5603 +3 598 4628 7454 +3 6692 3388 4341 +3 5208 5573 5603 +3 3197 1684 5484 +3 3675 1710 816 +3 2575 1542 1068 +3 1542 2575 6698 +3 6274 2576 6609 +3 4626 6268 5721 +3 1371 1877 4489 +3 3362 5648 5644 +3 5553 2605 2345 +3 3594 2826 3618 +3 5062 1494 5659 +3 2722 943 6588 +3 1441 1966 6988 +3 3965 2579 1093 +3 3130 2580 1497 +3 5400 2581 5686 +3 5872 381 7518 +3 3764 4422 596 +3 898 3009 3212 +3 5686 2581 6037 +3 1315 3007 4194 +3 7450 2709 2441 +3 5907 5235 644 +3 4621 4622 3107 +3 2498 5105 811 +3 2345 2605 1703 +3 1115 2585 5741 +3 5741 2585 5740 +3 5749 2586 5748 +3 1127 2232 5764 +3 2502 2587 5252 +3 7194 2588 5766 +3 5766 2588 5769 +3 1245 1130 43 +3 7005 7099 722 +3 1758 3482 1235 +3 6192 5309 1814 +3 4364 204 5770 +3 5607 2592 5771 +3 2274 2501 1071 +3 113 5811 3343 +3 4752 838 1939 +3 5771 2592 6822 +3 1141 2594 5140 +3 7303 4752 1939 +3 5000 1100 1710 +3 7074 1158 7084 +3 998 5772 5791 +3 5791 5772 5793 +3 5143 765 2431 +3 1661 1658 1662 +3 2599 7025 1656 +3 2712 2999 1648 +3 1618 7523 307 +3 7219 2153 7512 +3 5813 2601 5861 +3 356 5211 1060 +3 5825 5827 1152 +3 1729 4577 4559 +3 1585 4953 2604 +3 2639 2691 2335 +3 5040 1363 1642 +3 590 6615 5380 +3 7513 3643 2998 +3 4370 4367 5845 +3 5845 4367 5843 +3 4610 4611 3776 +3 3114 889 6704 +3 3545 5589 7141 +3 2931 2950 4421 +3 6478 6373 4770 +3 1165 2608 5851 +3 5851 2608 5852 +3 143 105 7158 +3 1501 5887 6590 +3 1501 5886 5887 +3 2612 5899 3370 +3 5065 2613 5899 +3 6033 1469 6024 +3 5899 2613 3767 +3 4485 3846 639 +3 5007 7478 5917 +3 1178 5284 4833 +3 2614 5923 1183 +3 2624 5930 1186 +3 587 4608 720 +3 5930 2624 5932 +3 5131 2625 1191 +3 2625 5935 6300 +3 582 4605 219 +3 785 2644 6072 +3 6228 5947 1681 +3 5956 6160 813 +3 2249 2663 612 +3 222 2627 5957 +3 5957 2627 5959 +3 5962 2628 5964 +3 3145 3228 4682 +3 5005 4600 4777 +3 1211 1558 989 +3 1360 2632 5983 +3 4596 4597 1220 +3 5988 4373 21 +3 5988 2633 6045 +3 7467 7399 7469 +3 3595 7121 250 +3 6546 5849 1164 +3 4813 2637 6009 +3 6010 1229 97 +3 6719 4588 6372 +3 2968 1727 3870 +3 1231 5614 6025 +3 4026 7217 1137 +3 2964 5173 4585 +3 1238 2640 6037 +3 4582 5657 1271 +3 6439 2695 6041 +3 5396 4984 6034 +3 3840 2642 6055 +3 3685 6061 1243 +3 220 2643 6062 +3 6062 2643 6280 +3 6068 3464 1248 +3 7341 7018 3968 +3 1751 4340 6526 +3 6072 5937 785 +3 1249 926 6073 +3 6073 926 2662 +3 2647 6080 1256 +3 2647 6083 1260 +3 4582 1271 1266 +3 7460 6103 2872 +3 7203 2661 2771 +3 6850 6863 7198 +3 6114 4243 5004 +3 6186 2651 1286 +3 1286 2651 6160 +3 3152 1963 125 +3 88 2690 6168 +3 1158 7500 7084 +3 5050 6834 3991 +3 6179 2655 4239 +3 4239 6091 6179 +3 186 2656 6195 +3 2656 6199 1297 +3 6947 2658 6199 +3 6199 2658 1297 +3 5193 2660 6206 +3 6206 2660 6208 +3 6073 2662 6209 +3 2662 7414 1875 +3 2121 6594 2638 +3 6347 98 6220 +3 5523 5356 6220 +3 3524 3651 2436 +3 5511 2666 6223 +3 6223 2666 6225 +3 2632 1322 6322 +3 3642 2669 6239 +3 6239 2669 6242 +3 4853 2673 1327 +3 5073 5320 2926 +3 1041 2679 6252 +3 6409 3399 3405 +3 4534 5269 4547 +3 1639 2547 5835 +3 7284 2675 1897 +3 453 6771 3021 +3 6445 2677 1897 +3 7453 1335 99 +3 1847 6261 7362 +3 5478 856 7042 +3 4570 4571 3797 +3 2678 6269 1341 +3 6252 2679 6269 +3 6609 2681 6274 +3 1348 2682 6278 +3 2266 6304 1353 +3 2564 484 1486 +3 5003 2683 1359 +3 6309 2684 5003 +3 6312 6313 2596 +3 2685 6325 1362 +3 6325 2685 3750 +3 6330 1368 461 +3 2965 6343 1373 +3 6343 2965 6342 +3 3991 2741 2380 +3 1330 2532 2638 +3 6349 6352 1376 +3 1377 2692 1379 +3 6320 4330 318 +3 4330 6320 3453 +3 6375 1378 100 +3 1318 6381 6379 +3 1366 474 1699 +3 6270 656 4576 +3 6379 1289 1318 +3 6279 6193 1708 +3 900 1383 6381 +3 4350 7135 4567 +3 1384 7163 435 +3 6041 2695 6385 +3 5355 5264 6390 +3 6390 6392 5355 +3 2698 6393 1396 +3 6393 2698 236 +3 1652 6626 2024 +3 6377 5928 6415 +3 3276 1417 6418 +3 2706 6434 1421 +3 5180 4143 2993 +3 672 1880 615 +3 5617 2443 2479 +3 7121 3595 7123 +3 6949 2618 6444 +3 99 2710 6445 +3 572 2402 679 +3 1927 6446 7505 +3 4451 1926 101 +3 3858 6630 2310 +3 6054 578 6455 +3 6455 578 6457 +3 5305 4560 6552 +3 4665 4791 4556 +3 3898 1608 2715 +3 2715 1608 6466 +3 3632 6284 3444 +3 6466 1443 3561 +3 6058 2716 6497 +3 6148 4555 4547 +3 7497 1919 662 +3 3506 2717 6502 +3 6502 2717 6605 +3 5171 2720 6507 +3 6516 2721 6515 +3 3797 4571 774 +3 4764 1914 3921 +3 6757 6773 2667 +3 3397 5936 2723 +3 6977 4599 5532 +3 3626 5041 4634 +3 1270 6094 6570 +3 6570 6094 5657 +3 2729 6591 2392 +3 4701 4990 4544 +3 5109 6624 6625 +3 733 471 7139 +3 2697 2671 6897 +3 2638 4401 2121 +3 3620 2520 749 +3 5925 2735 6658 +3 7139 5222 733 +3 1710 1100 1853 +3 5868 2736 6659 +3 1330 4188 792 +3 6659 2736 6663 +3 6675 6040 1536 +3 2743 6679 1929 +3 2744 6706 3087 +3 6706 2744 6709 +3 6713 6403 6715 +3 4313 4288 1551 +3 7521 6215 4050 +3 2745 6728 1555 +3 6728 2745 6727 +3 7440 6143 6545 +3 2401 3025 820 +3 6545 1603 7440 +3 3109 2847 6752 +3 6760 6546 5659 +3 2563 5979 5343 +3 480 3164 1457 +3 7321 2265 3341 +3 2747 3253 1569 +3 1492 2748 6770 +3 4540 4577 6526 +3 5048 5221 6284 +3 6351 4538 397 +3 6197 3344 797 +3 2383 1579 6776 +3 3082 5374 2898 +3 7401 4494 4037 +3 2751 6788 1112 +3 5854 2752 6804 +3 1513 2160 2085 +3 1954 6383 4533 +3 1586 2753 6805 +3 554 1668 1998 +3 3593 7127 4720 +3 6807 2754 6808 +3 2770 1653 6266 +3 5116 6297 5586 +3 5204 2760 6814 +3 2619 1523 7464 +3 54 2761 6831 +3 6822 2762 6824 +3 1598 2763 6827 +3 20 1600 2221 +3 1240 2766 6829 +3 6829 6044 1240 +3 1973 588 6306 +3 6845 4170 852 +3 6411 3399 6409 +3 123 6878 1616 +3 7046 5558 1671 +3 6887 1621 4308 +3 4455 2773 6900 +3 6900 2773 6898 +3 6912 2979 6916 +3 6595 2774 6937 +3 6937 2774 6939 +3 4686 2775 1630 +3 1630 2775 7352 +3 2776 6945 7095 +3 2776 6947 1587 +3 5858 2363 6690 +3 2777 1854 1635 +3 1637 6580 3306 +3 3306 6953 1637 +3 6970 4979 3762 +3 2444 2959 5597 +3 6970 2779 2557 +3 1803 2943 1107 +3 5529 6358 4528 +3 7358 5631 4523 +3 3681 4072 1722 +3 1647 2781 7005 +3 7281 5562 6794 +3 7273 7016 1651 +3 4434 1007 1183 +3 2865 1657 5818 +3 6575 2785 7031 +3 2785 1661 1662 +3 4179 881 6222 +3 7040 5301 1667 +3 904 2786 1657 +3 191 1618 7507 +3 5474 5288 1672 +3 4778 2788 7047 +3 7047 2788 5474 +3 4909 2789 7048 +3 4751 6411 2991 +3 2789 7050 1676 +3 105 1680 7158 +3 3609 2792 7297 +3 4381 1037 2468 +3 2573 5976 2314 +3 4347 1683 2837 +3 3606 2406 3469 +3 7108 6985 4522 +3 1653 2770 6690 +3 2796 7067 1688 +3 6313 1722 1650 +3 1689 109 1948 +3 7441 307 6549 +3 2801 7079 6024 +3 3422 1702 1700 +3 7082 7080 1702 +3 4742 7089 2876 +3 7338 2793 7089 +3 3280 6858 2724 +3 6858 2346 3971 +3 2806 7154 1719 +3 7154 2806 7152 +3 7199 6955 4515 +3 6408 2919 5692 +3 4601 4932 5278 +3 2807 1728 1724 +3 1728 2807 7169 +3 7170 6185 699 +3 6932 2811 7172 +3 2811 7323 1830 +3 6767 1737 6296 +3 7398 198 7184 +3 4287 2814 1906 +3 1906 2814 7469 +3 1747 2815 1768 +3 2815 7235 1768 +3 74 1756 7417 +3 5754 1838 1940 +3 5768 7234 1767 +3 6670 6542 771 +3 7196 1746 4513 +3 1776 7246 1772 +3 29 2823 7285 +3 6857 2821 3646 +3 2817 7268 1778 +3 7268 2817 7271 +3 3918 2818 1784 +3 1785 2819 7273 +3 7282 2820 7284 +3 1794 2822 7284 +3 4506 4507 5122 +3 7284 2822 7282 +3 7285 2823 7287 +3 3933 613 661 +3 6121 3228 2821 +3 6273 2825 7295 +3 7295 2825 1809 +3 1576 2141 7507 +3 1815 2827 7153 +3 6834 7092 2741 +3 6478 1142 2155 +3 2919 6408 2174 +3 363 2155 7096 +3 2794 809 3545 +3 1522 2196 1520 +3 2908 3002 85 +3 7304 7471 7442 +3 3395 1332 2816 +3 2652 6560 4502 +3 109 2830 1948 +3 660 5404 4499 +3 2760 5436 4757 +3 1824 2830 7310 +3 6865 4498 4497 +3 6328 2832 1829 +3 1829 2832 7354 +3 3499 1703 6844 +3 7340 7338 1835 +3 7061 2837 7340 +3 2493 6579 1912 +3 7343 2838 7345 +3 5696 2839 7345 +3 4504 6408 7349 +3 2841 7360 1844 +3 7360 2841 7362 +3 5587 2843 1857 +3 7167 2844 7381 +3 4520 4284 7180 +3 7205 2846 7396 +3 2849 7406 1868 +3 7406 2849 7405 +3 2025 2022 4490 +3 6253 2850 7412 +3 7413 6592 559 +3 110 2850 7414 +3 5837 2808 380 +3 2852 7439 2854 +3 7342 2854 7439 +3 1603 3042 7440 +3 1703 3499 7083 +3 7440 3042 4518 +3 3600 2855 7447 +3 5807 2856 7452 +3 7452 2856 7455 +3 5576 287 2749 +3 7455 4531 2510 +3 2860 7462 5140 +3 1760 650 1770 +3 1770 1212 1760 +3 7462 2860 7465 +3 805 2859 2910 +3 1179 2861 7485 +3 7485 2861 7486 +3 4763 3662 915 +3 7495 7278 7497 +3 1371 4489 5005 +3 2866 7502 2071 +3 2866 7501 1922 +3 783 3720 131 +3 1933 7505 1928 +3 2069 7283 5344 +3 1513 4905 2160 +3 1618 7441 3634 +3 1949 3807 1947 +3 2869 2060 1742 +3 2060 2869 7147 +3 7147 2870 2060 +3 6589 614 6086 +3 6767 761 3240 +3 2871 6464 1955 +3 6464 2871 6214 +3 4186 2874 1989 +3 1989 2874 6513 +3 4939 7149 765 +3 1992 2877 1967 +3 5647 2052 3716 +3 3716 2052 1965 +3 3230 6942 4487 +3 4703 4481 2392 +3 5658 2577 5761 +3 2577 5389 2879 +3 2879 5761 2577 +3 5394 2533 2880 +3 2533 2621 6479 +3 2186 2808 3714 +3 3018 4882 2998 +3 7410 2514 5994 +3 1978 2881 4654 +3 2602 7305 76 +3 4654 2881 4740 +3 1102 2858 6136 +3 3125 2760 3038 +3 7101 2882 4390 +3 2882 4451 1984 +3 1906 4294 4287 +3 2884 3841 1990 +3 3841 2884 3812 +3 1267 1964 5518 +3 5518 1964 7038 +3 2886 7272 2004 +3 7272 2886 7294 +3 2014 5824 7205 +3 4796 4640 4479 +3 7205 5824 6555 +3 2664 1915 3079 +3 5601 2018 7122 +3 7122 7174 5601 +3 2283 2888 7122 +3 2034 7091 7116 +3 5059 5595 2565 +3 3827 2892 6708 +3 2892 6724 2024 +3 6442 924 2034 +3 5356 2894 6347 +3 6347 2894 6338 +3 5966 7006 2039 +3 1373 5246 174 +3 2555 3606 2393 +3 5882 2038 5966 +3 5630 6731 4474 +3 5812 2041 4735 +3 5812 4267 991 +3 3277 4510 3761 +3 3277 168 2044 +3 1489 2002 1301 +3 1993 2794 5602 +3 2044 2899 732 +3 5661 2900 5678 +3 5678 2900 5274 +3 5666 2901 5593 +3 6691 5549 5590 +3 2959 3345 5023 +3 6680 5434 5513 +3 6604 2902 5294 +3 1506 4404 568 +3 5294 2902 5274 +3 6815 2151 5247 +3 5443 2847 2335 +3 5065 3154 2764 +3 2905 4778 2097 +3 4693 2906 4687 +3 2906 4644 2099 +3 4757 4179 3038 +3 7426 5559 734 +3 5142 5469 4595 +3 4244 1039 3148 +3 916 163 1158 +3 7002 163 916 +3 2911 4455 6900 +3 2912 4413 2124 +3 947 2903 6719 +3 4413 2912 4389 +3 7157 6017 7160 +3 3677 816 3573 +3 4471 4472 4850 +3 2913 4380 2558 +3 4818 6326 1770 +3 4380 2913 4359 +3 6577 4214 4180 +3 4955 533 2391 +3 7428 125 7129 +3 2855 4118 7447 +3 4118 2914 4112 +3 6803 2915 4112 +3 2917 3838 2140 +3 3743 5322 962 +3 6121 2922 4297 +3 7219 5589 2790 +3 7290 3678 606 +3 6512 2930 4059 +3 3181 4730 3772 +3 5430 4700 2390 +3 6671 5934 3453 +3 1917 2920 2184 +3 2184 658 6448 +3 2921 7075 515 +3 7075 2921 1121 +3 5585 7068 7180 +3 2315 7083 3499 +3 1530 2037 3331 +3 422 3394 6465 +3 7366 6465 3394 +3 6624 2924 1181 +3 1181 2924 6919 +3 6685 3573 816 +3 3536 2925 6959 +3 4522 2927 7108 +3 5169 2928 2370 +3 6469 5890 4462 +3 4059 2930 4026 +3 2950 2931 3777 +3 4026 2930 4587 +3 5501 5488 610 +3 6166 2169 2932 +3 2933 2809 3027 +3 528 4456 1883 +3 4452 4453 1444 +3 2809 2933 3868 +3 122 7470 346 +3 3474 2934 3647 +3 3647 2934 5423 +3 6844 2236 3499 +3 6232 6124 3255 +3 585 1831 4607 +3 1831 2938 914 +3 3848 2939 7311 +3 7311 2939 7493 +3 2940 3031 2230 +3 3031 2940 1382 +3 367 6191 3978 +3 2457 2941 482 +3 6738 7353 7321 +3 457 2943 128 +3 128 2867 457 +3 3274 2944 6673 +3 5066 4333 2045 +3 6673 2944 7289 +3 4564 2945 2626 +3 2626 2945 1413 +3 14 5095 232 +3 4769 2946 124 +3 124 2946 1375 +3 2571 1033 2187 +3 3642 6239 1258 +3 2378 443 1137 +3 3985 5435 5198 +3 6139 2890 2858 +3 1430 5938 1869 +3 6115 3290 3310 +3 3668 963 3399 +3 3208 2951 1804 +3 2995 3333 3146 +3 1804 2951 3361 +3 128 2944 2867 +3 5023 5597 2959 +3 4421 2950 1314 +3 992 833 4333 +3 5439 2954 660 +3 660 2954 5405 +3 7463 2957 4822 +3 4822 2957 5786 +3 6628 2958 3215 +3 367 427 6065 +3 4442 4444 3944 +3 7108 2927 1295 +3 135 5343 2027 +3 3873 2962 6473 +3 3263 4705 4299 +3 1763 4536 1129 +3 120 959 4589 +3 7450 6016 2709 +3 2609 4956 6230 +3 5938 1430 1694 +3 4296 174 457 +3 5246 4271 174 +3 3361 2966 254 +3 254 2966 401 +3 2954 2967 4701 +3 3111 7344 4579 +3 2742 4918 134 +3 6736 669 7 +3 4701 2967 4994 +3 5784 4560 831 +3 4038 7336 4410 +3 6629 2969 7475 +3 2387 3981 6176 +3 7475 2969 4332 +3 7242 978 6913 +3 3804 2972 63 +3 2564 2258 484 +3 6599 2973 6081 +3 6081 2973 3419 +3 1521 6967 6971 +3 2161 6781 5778 +3 2690 88 6354 +3 3829 1486 2428 +3 2237 1214 714 +3 3484 2974 2976 +3 4188 1330 7513 +3 3484 2976 2165 +3 955 2976 3224 +3 517 4430 4237 +3 4124 289 4562 +3 5180 672 5546 +3 3657 2977 3633 +3 4605 3633 579 +3 13 5486 1952 +3 4374 2978 444 +3 837 2890 825 +3 5909 2979 6963 +3 1765 4770 6373 +3 6963 2979 6912 +3 552 137 1256 +3 1256 3669 552 +3 2941 2984 482 +3 482 6732 2457 +3 4426 7376 5296 +3 5669 2986 3231 +3 512 4423 2169 +3 2956 1278 5121 +3 3627 5636 4415 +3 3869 2987 928 +3 928 2987 1438 +3 4404 3998 4424 +3 4566 550 3068 +3 5174 5103 3617 +3 139 3267 4503 +3 6005 7018 7341 +3 7513 4882 4188 +3 2548 2992 714 +3 2956 7267 5136 +3 3181 3310 5695 +3 2531 3256 3294 +3 4562 1599 5499 +3 6085 5259 3993 +3 2994 2897 4698 +3 3742 5983 815 +3 535 4796 4479 +3 2996 6152 2441 +3 6152 2996 6763 +3 734 5559 1394 +3 6963 6912 1615 +3 6505 6738 3509 +3 5424 703 7385 +3 754 5113 157 +3 2947 5721 7015 +3 7239 4500 682 +3 4681 7115 7104 +3 1733 2999 6353 +3 4513 142 6566 +3 1920 7497 2303 +3 2007 3000 5081 +3 2875 7478 388 +3 2267 4021 389 +3 4205 5436 7186 +3 3379 3003 3425 +3 6353 2999 2712 +3 7015 4795 3336 +3 3425 3003 3653 +3 6540 3686 7433 +3 556 6133 4409 +3 886 5135 889 +3 5639 4758 4192 +3 278 3005 4537 +3 3990 3008 5 +3 4818 3010 6326 +3 6326 3010 4495 +3 416 1352 6231 +3 5715 6458 6067 +3 5692 2740 3024 +3 4583 6824 3672 +3 6847 3014 6581 +3 2281 4614 2292 +3 3181 3772 3310 +3 2659 335 3028 +3 294 2117 3727 +3 5438 3016 2802 +3 2802 3016 3976 +3 3461 3017 4524 +3 4405 4407 6883 +3 2520 3620 465 +3 3389 3019 4947 +3 4947 3019 200 +3 1146 3020 1399 +3 3021 2540 5388 +3 3762 5715 2779 +3 1161 3022 1188 +3 3570 454 4424 +3 153 5278 4633 +3 5445 3023 3919 +3 3581 6626 280 +3 3791 3027 2809 +3 5085 4364 5770 +3 1944 3276 6418 +3 3057 3032 352 +3 2545 4007 3910 +3 2171 3033 5392 +3 155 501 4219 +3 4486 2444 6115 +3 1251 2546 3834 +3 2546 3036 4735 +3 3410 3037 1209 +3 4394 4395 2896 +3 1209 6782 3410 +3 455 2439 2639 +3 2498 4989 813 +3 2189 4439 5021 +3 6595 3039 1788 +3 503 4391 981 +3 1579 2383 412 +3 4878 3040 2218 +3 2907 4417 2950 +3 2947 3336 4525 +3 3996 5023 3345 +3 157 4393 3186 +3 2535 4388 309 +3 4614 2226 159 +3 3145 5721 7010 +3 5814 5352 3632 +3 159 5739 4614 +3 2660 161 288 +3 2734 1623 469 +3 3140 5679 5598 +3 288 4183 2660 +3 3631 5276 2739 +3 467 166 167 +3 3598 1444 167 +3 2600 2396 1261 +3 3606 3469 7515 +3 7096 1764 982 +3 2081 3045 4512 +3 1164 3045 4592 +3 2624 4387 5865 +3 902 2714 4828 +3 2948 4881 3686 +3 2497 3996 6250 +3 4706 3046 487 +3 487 3046 7164 +3 6664 4016 3916 +3 4486 3047 1735 +3 2116 6981 4483 +3 3048 1284 6113 +3 5563 6762 2282 +3 2436 1134 5099 +3 3049 3994 2805 +3 5104 3051 3797 +3 1602 3051 3486 +3 1173 3052 6425 +3 1134 2436 626 +3 3545 809 5589 +3 6425 3052 6785 +3 5118 3053 3075 +3 3075 3053 5313 +3 2219 853 1660 +3 2379 3341 652 +3 454 568 4404 +3 7240 3057 1207 +3 2924 3058 2325 +3 2325 3058 3402 +3 2969 3059 3796 +3 3796 3059 3324 +3 3093 3060 7156 +3 2177 283 6686 +3 3898 5479 1608 +3 242 177 4624 +3 7009 4379 707 +3 3631 2311 5276 +3 5085 168 4364 +3 2540 3021 6771 +3 1119 1722 1627 +3 2586 4680 6007 +3 3146 2455 6265 +3 3044 5463 5465 +3 5856 3069 5873 +3 7093 3747 2797 +3 1391 3071 2180 +3 5818 7024 1911 +3 2177 5549 283 +3 2064 2225 36 +3 281 5037 3123 +3 4579 2244 3111 +3 6447 2232 170 +3 6447 3074 7097 +3 6065 1189 367 +3 2961 3076 1407 +3 629 7318 2836 +3 2376 5815 490 +3 1407 3076 6440 +3 5885 4801 690 +3 2135 3255 6946 +3 1357 3370 3767 +3 3388 6692 5281 +3 3729 4082 7457 +3 3167 2594 1141 +3 4525 3078 2704 +3 2990 2425 2183 +3 2990 2183 57 +3 4023 2331 4993 +3 3913 3325 7404 +3 7097 3080 5687 +3 6365 6552 3582 +3 4370 4368 44 +3 3420 3081 6867 +3 2645 2664 5106 +3 3082 1161 1099 +3 1161 3082 3022 +3 3702 4895 6978 +3 5246 2946 1196 +3 4363 1156 5587 +3 3031 1382 2970 +3 2944 3085 2867 +3 2867 3085 2744 +3 174 2965 1373 +3 6785 3088 5651 +3 5651 3088 4084 +3 3177 3089 3305 +3 6303 3091 4025 +3 6239 3092 1258 +3 5533 2062 4697 +3 1258 3092 1241 +3 4361 3184 5702 +3 3350 3093 25 +3 6504 4136 1484 +3 175 3149 3715 +3 1033 2571 1045 +3 3197 3672 418 +3 2433 3097 6337 +3 6824 4583 1596 +3 3098 5815 3808 +3 3690 3571 4225 +3 5815 3098 3099 +3 482 3099 6732 +3 716 4428 624 +3 6732 3099 3097 +3 5164 6481 6868 +3 1446 1578 5875 +3 6597 3100 4593 +3 666 3101 679 +3 3155 6002 3293 +3 5463 3044 2275 +3 3101 4561 572 +3 3940 6994 1047 +3 6460 5707 5809 +3 5449 5427 5376 +3 3221 3103 24 +3 4936 3104 4891 +3 1949 3105 5840 +3 5840 3105 4114 +3 2454 1151 3180 +3 4029 2705 3543 +3 5477 4288 165 +3 3137 3814 5884 +3 759 3111 6792 +3 3166 3113 7204 +3 7204 3113 6430 +3 3267 558 437 +3 521 4690 2089 +3 7415 1083 4961 +3 3103 3115 2394 +3 4352 1775 5713 +3 1559 3067 1013 +3 2394 3115 6227 +3 5154 5484 1684 +3 6901 6032 62 +3 1486 3829 1713 +3 2508 3118 3904 +3 3904 3118 4986 +3 2310 4023 4993 +3 5278 391 4601 +3 3768 3120 5021 +3 5021 3120 390 +3 960 4645 4136 +3 4435 5684 4424 +3 990 287 82 +3 4476 863 7409 +3 6363 5482 3349 +3 178 5782 6363 +3 3429 3123 6264 +3 2551 3124 1034 +3 1034 5047 2551 +3 4994 3127 2989 +3 2989 3127 4642 +3 3731 3128 4850 +3 2580 1404 1252 +3 6512 4059 4770 +3 3852 3137 1725 +3 2707 4349 6941 +3 2834 1016 182 +3 182 3480 2834 +3 7075 1121 183 +3 183 3520 7075 +3 2928 3136 2370 +3 2370 3136 267 +3 3138 7103 2136 +3 7103 3138 329 +3 1720 4345 4349 +3 6311 1579 412 +3 6943 808 3572 +3 5270 5627 4755 +3 2504 185 5414 +3 3073 5414 185 +3 3447 3144 6832 +3 756 319 1976 +3 380 1450 5837 +3 1013 3067 5459 +3 1330 6594 7513 +3 2073 7496 71 +3 4359 4727 2978 +3 5162 6717 4209 +3 3830 3147 844 +3 3147 4574 3151 +3 701 3416 2726 +3 3370 1357 1240 +3 2085 3153 1513 +3 7402 3893 6127 +3 4642 3156 6043 +3 6043 3156 7193 +3 2704 202 1783 +3 809 6427 3755 +3 4244 7043 4182 +3 5427 2991 6411 +3 4378 7417 3158 +3 1136 5832 5608 +3 3158 3159 4077 +3 4077 3159 6700 +3 3682 3162 693 +3 6700 6842 3814 +3 3902 1110 476 +3 2279 5325 691 +3 187 840 6477 +3 3164 3287 3288 +3 148 3166 4617 +3 4617 3166 5390 +3 6643 4660 4705 +3 3323 5575 5655 +3 1451 822 6471 +3 3153 3168 1513 +3 1513 3168 1688 +3 1364 969 5348 +3 1364 3169 5605 +3 2531 3294 2460 +3 2419 4517 933 +3 5180 1880 672 +3 4043 3173 4985 +3 6481 393 2993 +3 7430 3950 7045 +3 3103 3174 24 +3 7318 603 6636 +3 24 3174 6856 +3 2448 3175 4542 +3 2970 6531 3031 +3 4631 3177 5690 +3 5690 3177 5001 +3 4705 4660 4299 +3 5822 3219 6501 +3 3052 3178 3305 +3 4414 2749 287 +3 4232 6911 2700 +3 816 3677 793 +3 4730 3181 7215 +3 3639 3184 3584 +3 7509 3184 927 +3 999 7466 6070 +3 7348 3185 5129 +3 5402 3187 1498 +3 1498 3187 6964 +3 7517 1686 7231 +3 4847 3188 4457 +3 4457 3188 6551 +3 5916 3446 6012 +3 3272 3190 3289 +3 6089 3194 456 +3 456 1954 6089 +3 4197 718 2467 +3 6749 452 456 +3 1723 3199 2206 +3 4336 138 3599 +3 5094 6023 4331 +3 5693 7319 1366 +3 3916 1633 6664 +3 1627 1722 4072 +3 5312 5942 5221 +3 7055 3200 6228 +3 3200 5093 5946 +3 4016 6463 172 +3 5041 3626 4584 +3 2182 3203 1509 +3 1509 3711 2182 +3 3423 1562 193 +3 5408 4378 4077 +3 2166 194 830 +3 6594 2121 7519 +3 830 480 2166 +3 2335 2691 3303 +3 3287 3206 832 +3 832 126 3287 +3 4731 5072 4211 +3 5619 5087 7450 +3 7146 4321 5816 +3 2367 1985 6693 +3 6336 3540 4733 +3 5597 5023 3096 +3 5460 1649 4710 +3 6481 5164 2728 +3 1880 2379 652 +3 1650 1119 3964 +3 6494 4275 3243 +3 5430 2390 2202 +3 347 4320 3738 +3 3533 3207 341 +3 6621 4055 5624 +3 3887 3208 6511 +3 958 3165 1361 +3 708 5243 6038 +3 5023 1463 3096 +3 3210 3670 1538 +3 4136 4645 2065 +3 405 808 5680 +3 5680 1497 405 +3 200 3020 4947 +3 192 1822 1823 +3 4327 4325 3582 +3 2819 4323 2238 +3 3582 2653 4327 +3 192 3214 1749 +3 4072 4051 1627 +3 2117 6630 3858 +3 6473 2962 6645 +3 1544 3375 1488 +3 3914 5699 6716 +3 3714 6647 2186 +3 5485 6282 1934 +3 1072 5133 4322 +3 5470 4688 5068 +3 3218 4035 4722 +3 5289 3292 1723 +3 3115 3221 5668 +3 4200 211 3223 +3 1210 3802 435 +3 5403 3629 1221 +3 5555 6272 1885 +3 5056 2982 5997 +3 2664 2645 1915 +3 3219 6500 7252 +3 2165 4428 3484 +3 682 3225 7239 +3 7239 3225 3226 +3 3976 3226 2997 +3 2997 3226 3224 +3 3163 3227 2279 +3 2279 3227 4790 +3 2768 4953 4129 +3 2763 4317 5668 +3 87 1954 4533 +3 6600 5796 1567 +3 606 619 295 +3 328 2205 5980 +3 3231 6790 5669 +3 6790 328 1216 +3 2439 3109 791 +3 4112 3222 6803 +3 4303 2746 5599 +3 1281 3235 3566 +3 339 195 3842 +3 3446 1821 4672 +3 6059 3239 5191 +3 4168 3241 1502 +3 1502 3241 6283 +3 1014 2602 2812 +3 2568 3244 3576 +3 3576 3244 207 +3 1734 2495 6487 +3 697 7010 6268 +3 3964 4414 6643 +3 6924 1564 6750 +3 2366 707 4379 +3 3653 3246 3463 +3 3463 3246 531 +3 4324 3590 5137 +3 3250 3249 130 +3 130 3249 5137 +3 207 4780 3576 +3 4059 1142 6478 +3 4959 3250 2482 +3 2482 3250 675 +3 801 3165 4835 +3 603 1810 6004 +3 3251 3094 3668 +3 488 5093 203 +3 4440 7224 4857 +3 5408 454 3570 +3 203 3966 488 +3 3252 2364 4561 +3 2584 6707 4995 +3 7009 3480 1568 +3 206 4572 798 +3 339 306 752 +3 7463 3258 306 +3 7404 7256 7520 +3 6384 3259 4298 +3 4298 3259 5349 +3 4416 3260 5492 +3 5950 930 1339 +3 4659 3144 3447 +3 5674 3262 2893 +3 2893 3262 308 +3 675 6071 2482 +3 6879 3265 3664 +3 3664 3265 5088 +3 5026 3266 4548 +3 3116 6940 1884 +3 5201 1712 6320 +3 3945 2188 139 +3 2513 3268 3269 +3 6882 3183 3179 +3 7141 2418 3545 +3 464 3263 2670 +3 3120 3269 7173 +3 7173 3269 3268 +3 4136 4005 960 +3 3104 3270 829 +3 829 4891 3104 +3 2358 3271 4623 +3 4295 3272 2629 +3 2938 585 3676 +3 2629 3272 4963 +3 209 3037 2096 +3 210 6169 1289 +3 3085 3274 3275 +3 227 2435 1118 +3 2435 3275 6820 +3 2933 3027 1269 +3 1414 5085 3030 +3 4510 3277 732 +3 3312 3278 6315 +3 1939 838 4020 +3 6315 3278 4395 +3 4641 3279 3680 +3 5243 94 6396 +3 3279 213 2220 +3 2389 6102 1423 +3 3038 2760 4757 +3 3223 297 4200 +3 3223 3282 5555 +3 3220 3282 213 +3 646 6813 3702 +3 4743 5457 4309 +3 1938 4050 6215 +3 213 5289 3220 +3 4194 2495 5767 +3 2828 5287 5723 +3 3239 3283 5191 +3 5191 3283 6496 +3 2403 3286 126 +3 5508 1881 6423 +3 3206 3164 480 +3 3568 2157 7000 +3 3288 840 3164 +3 79 2083 2296 +3 5800 4762 620 +3 2296 3288 3286 +3 3263 1603 4705 +3 3279 3291 5289 +3 6803 3222 860 +3 5762 6865 4304 +3 3292 5289 215 +3 3199 3292 6104 +3 6104 3292 2222 +3 4360 7322 5453 +3 6978 2091 3702 +3 1463 3294 1104 +3 155 3295 3296 +3 3233 515 5944 +3 3047 7327 1735 +3 7327 3296 3717 +3 4032 3298 3133 +3 4169 2478 3754 +3 3133 3298 1555 +3 3299 4189 839 +3 5442 7347 127 +3 4346 3515 1869 +3 4189 3299 6039 +3 4743 6071 41 +3 41 5456 4743 +3 1290 3300 4600 +3 3721 3302 7012 +3 3302 6557 7337 +3 4486 3772 4399 +3 4017 5199 6660 +3 981 4391 4293 +3 6115 3772 4486 +3 5998 3307 1777 +3 1673 3308 3309 +3 6496 3309 3650 +3 3650 4886 6496 +3 6554 1323 7151 +3 3040 3311 671 +3 1422 3312 3544 +3 3040 3315 2218 +3 5301 7040 1712 +3 1 2902 7343 +3 2218 3315 4473 +3 4591 1564 3141 +3 4261 6751 1239 +3 1044 6040 6236 +3 1956 2831 5166 +3 22 3147 3830 +3 156 120 3662 +3 3668 6494 3251 +3 22 3318 276 +3 219 5972 582 +3 2863 761 6276 +3 4665 4556 4290 +3 1443 219 3319 +3 2524 5524 3724 +3 4430 3320 4237 +3 4237 3320 4240 +3 5895 3172 588 +3 4620 3629 5403 +3 7407 5633 1981 +3 6652 2771 7148 +3 5374 7019 2653 +3 638 5614 1231 +3 3931 6716 7037 +3 5156 3596 2742 +3 5314 3196 1593 +3 3060 3059 7156 +3 3877 3326 1200 +3 1200 3326 6639 +3 4980 3327 2064 +3 7042 6067 5235 +3 2064 3327 2225 +3 2493 7000 7159 +3 3329 3377 6512 +3 515 3233 2921 +3 3377 3329 6928 +3 3418 3330 6021 +3 1604 6200 1020 +3 6021 3330 6519 +3 231 94 7053 +3 847 3952 1177 +3 4284 4279 4177 +3 94 4918 7053 +3 3623 3335 25 +3 6965 1262 7437 +3 6711 1548 3337 +3 2341 3917 6382 +3 1916 4010 4201 +3 1215 3385 5973 +3 426 3338 3680 +3 5046 31 5604 +3 2615 5078 5022 +3 3000 7302 511 +3 3000 3749 3753 +3 7379 3342 6644 +3 4655 3347 3880 +3 3885 6460 3578 +3 7178 3217 223 +3 2664 2607 5106 +3 223 3846 7178 +3 3060 3350 3301 +3 5416 3351 6721 +3 2607 1729 5106 +3 6721 3351 3352 +3 3335 3352 25 +3 25 3352 3350 +3 3799 3353 671 +3 3315 3354 5049 +3 5049 3354 3511 +3 7022 5939 224 +3 224 5418 7022 +3 3753 3356 5081 +3 5081 3356 2068 +3 1682 3357 710 +3 3357 4842 710 +3 961 3358 6983 +3 2205 6853 3424 +3 3293 470 1224 +3 1358 593 2966 +3 502 1475 536 +3 4165 6222 881 +3 6680 7384 7281 +3 6994 3102 1704 +3 3366 5833 2650 +3 4152 3367 5583 +3 4291 3368 5960 +3 2524 6305 6287 +3 5462 3676 1421 +3 3369 6231 1352 +3 6879 6350 2373 +3 2595 3310 3290 +3 2162 3539 260 +3 2162 3371 1145 +3 3596 340 3198 +3 1083 3372 3532 +3 3587 6372 2766 +3 6375 6354 3026 +3 4709 5298 7498 +3 1285 1437 4841 +3 2764 3154 172 +3 7319 5693 6959 +3 2131 1609 6867 +3 3034 6534 4270 +3 2361 3999 5 +3 2435 5720 1118 +3 4265 4266 5760 +3 227 6703 4438 +3 1725 4406 3852 +3 1488 3375 3525 +3 7133 3379 3467 +3 3467 3379 4103 +3 3380 3706 3396 +3 2478 5515 5056 +3 804 3336 3718 +3 3706 3380 5935 +3 3019 3381 7102 +3 7102 3381 1128 +3 2328 1127 4196 +3 2251 4262 4602 +3 2496 3384 2236 +3 1235 3897 351 +3 1827 3387 1280 +3 1280 3387 350 +3 772 5801 4257 +3 3381 3389 4196 +3 847 1177 1895 +3 1895 7169 2807 +3 6511 84 2868 +3 6289 3581 228 +3 1105 7041 5540 +3 2164 4288 5477 +3 2361 5 4254 +3 1506 3137 3852 +3 6034 3393 718 +3 7366 3394 2428 +3 2428 3394 6895 +3 1885 3223 5555 +3 1885 297 3223 +3 3398 4774 764 +3 4774 3398 1480 +3 555 3401 403 +3 1002 7186 5437 +3 403 3261 555 +3 4459 1532 7240 +3 3686 7119 2948 +3 3724 3628 2524 +3 4724 3403 1491 +3 1491 3403 6422 +3 3675 3540 5000 +3 3458 3404 4884 +3 5119 3406 230 +3 6341 2755 230 +3 3478 3407 516 +3 3593 4720 7110 +3 6170 3408 3410 +3 3410 6782 6170 +3 7201 4458 1103 +3 5724 2386 3754 +3 1103 3407 7201 +3 5253 1346 4276 +3 1993 4814 1342 +3 232 4161 14 +3 6286 3411 4259 +3 4259 3411 5711 +3 707 2366 1716 +3 7380 6827 4252 +3 6396 2875 3001 +3 3307 4881 1777 +3 4881 3307 7433 +3 7200 5423 2119 +3 1557 7386 2740 +3 2992 3413 714 +3 3413 235 2237 +3 3505 2117 3858 +3 4523 3414 7358 +3 3530 3414 235 +3 235 354 3530 +3 4611 3418 3776 +3 2972 2973 63 +3 6081 3419 3565 +3 736 2569 5599 +3 3498 3420 5432 +3 60 1137 443 +3 5432 3420 4171 +3 1332 2536 1469 +3 4248 1108 2176 +3 3258 3421 752 +3 752 3421 458 +3 1386 1562 1092 +3 2205 3424 5980 +3 309 3426 148 +3 1086 4033 4712 +3 1086 5459 4033 +3 3001 6957 6396 +3 6790 3510 5669 +3 3429 4312 3203 +3 4312 3429 3793 +3 204 5811 1560 +3 3336 2947 7015 +3 3793 5130 5015 +3 4103 3430 2476 +3 3161 7195 2360 +3 6685 816 1710 +3 730 5476 2567 +3 1399 3431 1146 +3 1146 3431 4716 +3 1559 3432 239 +3 474 1366 5542 +3 717 1559 239 +3 1045 7007 557 +3 4127 3730 1160 +3 240 1614 6783 +3 240 3432 1614 +3 2116 243 5623 +3 243 5548 5623 +3 7168 7084 7500 +3 3234 3988 4880 +3 1738 918 3216 +3 6851 3435 5397 +3 289 7409 863 +3 1097 1254 3948 +3 4242 2997 4241 +3 3782 3438 4552 +3 5914 3440 3627 +3 3627 3440 5638 +3 2920 3442 7470 +3 7470 3442 346 +3 1647 3443 2591 +3 2591 3443 345 +3 3323 2574 4432 +3 2612 1240 6044 +3 5466 6951 5188 +3 4649 4892 1160 +3 4114 3449 4588 +3 1262 6965 2337 +3 1900 5969 5522 +3 581 3454 3455 +3 1714 121 7134 +3 121 3455 3456 +3 228 634 6289 +3 3455 5122 581 +3 4714 121 3456 +3 1973 6306 623 +3 584 3720 2310 +3 3562 3457 4884 +3 5728 3458 3107 +3 3107 3458 4621 +3 6361 7110 4720 +3 3459 4036 5755 +3 3386 3121 3661 +3 7374 1291 573 +3 5427 6411 4840 +3 131 584 3135 +3 4036 3459 2016 +3 5608 3460 11 +3 11 3460 6658 +3 3542 3461 2780 +3 5910 3464 3756 +3 2400 3465 5974 +3 4234 993 1669 +3 5974 4530 2400 +3 3270 3466 3261 +3 2295 5249 2756 +3 3245 2756 5249 +3 3293 6002 6003 +3 246 5839 6741 +3 2625 3468 3706 +3 3493 3470 201 +3 201 3470 6640 +3 3865 7366 7130 +3 1935 3906 1602 +3 4231 4229 3487 +3 4993 584 2310 +3 2179 5782 248 +3 248 3472 2179 +3 1819 2190 637 +3 3472 0 49 +3 3988 3234 2420 +3 3155 4356 2248 +3 2248 396 3155 +3 4264 3474 6173 +3 4837 6499 3192 +3 5310 3475 5874 +3 2021 6896 6840 +3 910 5450 909 +3 2727 6896 973 +3 253 7187 7288 +3 6957 3001 944 +3 4224 4226 3142 +3 778 4815 692 +3 6484 3478 385 +3 385 3478 6620 +3 7119 6540 1268 +3 3486 394 3994 +3 3432 3649 1614 +3 3482 6026 350 +3 6971 3483 1521 +3 1521 3483 4133 +3 7280 2115 6797 +3 7518 6006 2700 +3 3201 4241 2974 +3 5354 3201 970 +3 978 3585 6913 +3 4395 3485 2896 +3 5154 3585 5010 +3 2962 4075 4369 +3 4369 4075 4622 +3 5224 5918 5138 +3 881 6828 4222 +3 3343 3487 113 +3 3490 2261 2170 +3 4218 4219 501 +3 4010 7256 4009 +3 2384 3491 5683 +3 5683 3491 5339 +3 259 3488 7491 +3 433 4215 4548 +3 3488 3492 4901 +3 1650 6643 3663 +3 2355 4648 4968 +3 427 1099 1161 +3 7401 4365 4494 +3 6633 3493 6414 +3 6490 5794 2254 +3 4985 3495 2594 +3 6875 5309 3795 +3 2594 3495 5140 +3 584 2373 3135 +3 3081 3498 4859 +3 2091 3500 646 +3 646 3500 2756 +3 2353 643 1621 +3 841 4445 426 +3 2778 4708 2988 +3 271 260 4120 +3 271 4120 4121 +3 3786 3502 524 +3 82 287 4199 +3 524 3502 404 +3 1575 3603 423 +3 6583 3503 4759 +3 4759 3503 3551 +3 2717 3506 899 +3 6173 5533 508 +3 6422 748 1491 +3 4020 7364 3139 +3 899 73 2717 +3 4998 3507 327 +3 1711 6217 7376 +3 4493 2352 1921 +3 5646 3510 6045 +3 6045 7436 5646 +3 3353 3354 671 +3 5049 3511 3604 +3 904 2865 1828 +3 4790 3512 3497 +3 1518 4625 6697 +3 5871 4511 6267 +3 4781 3513 3576 +3 4190 4192 4758 +3 5591 3513 4263 +3 3516 205 139 +3 266 2008 4732 +3 2761 3519 149 +3 827 3519 3997 +3 3997 3519 2255 +3 267 2195 2370 +3 7075 3520 5941 +3 5563 3521 6762 +3 999 3705 369 +3 2373 6350 3135 +3 3746 7163 1384 +3 3757 268 3523 +3 2928 3523 4723 +3 3525 4723 268 +3 1118 3375 227 +3 1488 3525 268 +3 1633 3236 3666 +3 4894 3613 5705 +3 531 3526 3463 +3 2824 3527 3355 +3 4404 3852 3998 +3 7003 3528 4726 +3 4726 3528 3857 +3 3529 4297 2922 +3 4297 3529 1165 +3 4409 3530 556 +3 269 2262 2725 +3 270 3621 3548 +3 3475 3531 6333 +3 6333 3531 6314 +3 6382 2636 5219 +3 5243 6957 6038 +3 420 933 324 +3 4555 4632 5100 +3 6717 4184 1519 +3 1560 5811 113 +3 3886 6238 3656 +3 3533 341 4497 +3 6427 5649 1077 +3 437 2196 3267 +3 4178 4275 2991 +3 1519 3534 4209 +3 4209 3534 4223 +3 6813 646 5752 +3 2918 2 2080 +3 2149 3737 5247 +3 2148 3889 2784 +3 6819 3536 1317 +3 1317 3536 6126 +3 3556 3537 5311 +3 5311 3537 6476 +3 5786 3538 2162 +3 404 3539 524 +3 524 3539 3541 +3 4527 1508 1061 +3 1061 3538 4527 +3 2520 4756 749 +3 3017 3542 3415 +3 3415 3542 6108 +3 5221 5942 5940 +3 3544 2103 1422 +3 2103 3544 1719 +3 4590 3750 2152 +3 3411 3546 4068 +3 4068 3546 6684 +3 3239 3547 4554 +3 272 7267 4782 +3 1455 7267 272 +3 1827 2147 6328 +3 840 2083 274 +3 274 6477 840 +3 2187 1477 5455 +3 4155 5015 6257 +3 569 3763 1251 +3 4172 4173 3608 +3 3931 447 2696 +3 3504 3503 2895 +3 2146 5319 1064 +3 1386 1092 1042 +3 3500 3553 4014 +3 3555 563 3556 +3 4131 3556 2527 +3 563 4539 4538 +3 982 363 7096 +3 7170 3557 1064 +3 276 579 2977 +3 1443 5972 219 +3 6867 4273 3420 +3 4098 3562 3563 +3 3901 3563 5364 +3 5364 3563 3574 +3 597 3564 5207 +3 5207 3564 4166 +3 3418 3419 3776 +3 3566 2458 1281 +3 2458 3566 6522 +3 2595 5409 2455 +3 6092 3567 264 +3 5507 4932 4440 +3 2689 4708 2449 +3 4166 4167 5207 +3 2267 3004 7213 +3 1262 4339 2687 +3 3001 2875 277 +3 5952 6793 6781 +3 277 3333 3001 +3 3228 4297 5420 +3 6121 6857 5006 +3 3784 3763 2518 +3 4646 5498 1052 +3 4098 3563 2163 +3 5364 3574 854 +3 3404 3575 4884 +3 4884 3575 850 +3 5331 3967 6346 +3 3810 3577 2048 +3 4637 2048 599 +3 3719 2344 1617 +3 3005 599 3577 +3 6034 2703 5396 +3 4076 4163 7013 +3 545 2652 4502 +3 5852 3784 5848 +3 6015 3935 1698 +3 3579 5377 1901 +3 3392 3580 7041 +3 280 1652 5653 +3 6626 3581 577 +3 2520 465 5375 +3 661 4885 3933 +3 1918 6969 2033 +3 2551 4228 3342 +3 3123 3124 6264 +3 3091 2488 225 +3 2488 3091 4717 +3 1614 3649 6740 +3 2917 2342 1255 +3 3719 6171 6222 +3 1025 1826 565 +3 6816 4508 6773 +3 5055 4982 4736 +3 4999 4427 702 +3 3405 5166 1801 +3 6608 3590 4225 +3 3590 4324 3690 +3 2182 3711 750 +3 281 5124 5037 +3 2356 4162 2714 +3 890 3192 452 +3 3592 5541 755 +3 5789 3671 7429 +3 5731 6382 2338 +3 1254 282 519 +3 1254 519 3948 +3 3690 6050 1241 +3 2337 5165 4339 +3 284 3671 7432 +3 2742 134 318 +3 2855 6743 921 +3 2299 2278 2645 +3 286 1199 19 +3 286 2277 1199 +3 4814 2981 1490 +3 288 166 4183 +3 4336 6990 2337 +3 4788 3599 138 +3 4441 3602 3827 +3 3827 5116 4441 +3 423 3603 2156 +3 1617 5952 1074 +3 3512 3511 3497 +3 2636 6382 3917 +3 2636 3605 6730 +3 1414 2044 5085 +3 769 7436 4354 +3 2139 5844 3837 +3 5509 3609 1769 +3 1769 3609 7297 +3 5223 3610 893 +3 893 3610 439 +3 2781 3611 3667 +3 4922 6940 423 +3 4250 3837 5844 +3 3612 929 1206 +3 2259 2018 5573 +3 2142 3837 4250 +3 6189 2888 3843 +3 3187 3614 5129 +3 6574 2046 1968 +3 7204 3618 5192 +3 2466 3619 6999 +3 3487 1912 113 +3 1912 4836 2493 +3 5412 465 5709 +3 2670 3618 2826 +3 5022 4837 5025 +3 981 4293 4153 +3 5025 4837 5265 +3 2725 974 269 +3 6667 4783 2340 +3 5996 6409 1801 +3 2140 6856 3175 +3 3548 3621 571 +3 3093 3622 25 +3 4711 5816 4151 +3 4119 6504 6066 +3 5993 3623 4549 +3 1330 2638 6594 +3 4549 3623 6298 +3 782 6727 2145 +3 3625 7371 1850 +3 4945 2483 2843 +3 6727 782 2138 +3 3716 1992 5647 +3 2013 1418 5982 +3 5122 3455 1714 +3 6433 7290 295 +3 2410 3638 3584 +3 3639 4335 1101 +3 214 196 594 +3 3290 2845 2595 +3 3526 3641 3463 +3 2952 1339 5781 +3 3450 6816 6757 +3 3463 3641 3803 +3 2669 3642 3025 +3 3642 1070 820 +3 6311 6454 2590 +3 1992 3716 5658 +3 2289 310 2309 +3 5530 3644 3862 +3 386 3645 1445 +3 3157 2947 2704 +3 5529 4528 3648 +3 4201 2049 1916 +3 3648 795 5529 +3 3309 3083 1673 +3 4970 4886 795 +3 3803 3652 3463 +3 3246 3003 4746 +3 3425 3653 4715 +3 2872 3794 1607 +3 5521 7364 838 +3 3915 3654 6294 +3 1295 3655 7108 +3 1107 3476 1803 +3 7108 3655 6984 +3 5332 3657 3928 +3 299 2200 1409 +3 4144 5102 3781 +3 2200 3658 3770 +3 6831 3660 5800 +3 4830 3755 498 +3 4142 4156 1405 +3 3600 1892 508 +3 359 4979 1640 +3 2197 3891 3923 +3 3637 5206 3795 +3 445 5272 5205 +3 4557 873 3665 +3 2895 5465 4140 +3 1705 3908 2654 +3 3667 154 2781 +3 154 3667 355 +3 3668 3094 919 +3 963 3668 5846 +3 4336 3599 6990 +3 6511 3208 84 +3 407 4138 7291 +3 1777 3640 4853 +3 1758 6367 4133 +3 3146 6265 2995 +3 1538 3165 3210 +3 7315 3790 4794 +3 3790 111 4729 +3 1804 3361 7383 +3 3405 3399 963 +3 343 3672 6824 +3 5269 4534 1972 +3 5493 162 2057 +3 1792 3673 6787 +3 993 4719 636 +3 4684 3674 7190 +3 3718 3336 4795 +3 7190 3674 7351 +3 2706 3676 304 +3 1908 3066 1745 +3 5178 4771 2334 +3 304 7290 2706 +3 303 3064 4662 +3 2288 3064 303 +3 2527 6352 4131 +3 3676 5462 2938 +3 4589 3662 120 +3 2524 3628 6305 +3 1934 3218 5485 +3 6910 3685 2713 +3 7480 3891 2197 +3 2713 3685 1243 +3 305 2933 3030 +3 2957 3688 4527 +3 2458 6524 4128 +3 6472 3689 3691 +3 3691 538 6472 +3 306 3258 752 +3 4875 3691 3688 +3 7243 6982 3637 +3 1655 1659 3140 +3 4803 2065 6064 +3 2503 3694 61 +3 61 3694 6720 +3 4331 3695 5094 +3 3777 2907 2950 +3 3638 3639 3584 +3 2649 3900 3891 +3 1346 3697 4276 +3 1852 2746 4067 +3 4754 6050 7227 +3 4276 3026 5253 +3 4495 3698 4731 +3 5561 6107 4125 +3 4731 3698 6249 +3 5795 3699 1761 +3 3199 3700 2206 +3 1512 3703 4861 +3 4861 3703 326 +3 3704 5440 448 +3 5440 3704 326 +3 2908 2057 162 +3 214 1470 2772 +3 2462 3708 5238 +3 5238 3708 4070 +3 3023 3710 3919 +3 1876 4401 310 +3 310 2291 1876 +3 3095 2289 869 +3 2441 4220 2996 +3 3690 3713 3571 +3 3713 3365 6389 +3 4343 3900 2649 +3 5535 3365 3713 +3 313 2750 1589 +3 3715 3149 6123 +3 2291 3715 2293 +3 2141 2530 5424 +3 7408 7411 118 +3 635 2953 4251 +3 3296 501 155 +3 3926 3979 1896 +3 2680 2931 3055 +3 5854 3926 35 +3 2873 3932 3926 +3 1972 3656 6238 +3 3297 96 4051 +3 1114 2620 1028 +3 1028 2750 313 +3 4030 5065 1172 +3 319 5181 1345 +3 3721 6885 1582 +3 7011 3932 2873 +3 6885 3721 6057 +3 3771 4508 3452 +3 843 3725 6279 +3 4123 4759 3551 +3 6279 3725 6151 +3 999 5163 5903 +3 59 4446 2130 +3 4446 59 3726 +3 445 3728 5836 +3 5836 5272 445 +3 4468 3245 6903 +3 3146 4917 2455 +3 439 2114 893 +3 3336 804 4525 +3 4121 6231 271 +3 1160 3730 5507 +3 1744 5451 950 +3 623 6306 6365 +3 4125 3731 5561 +3 5561 3731 4823 +3 4365 4193 317 +3 402 2332 3337 +3 317 5222 4365 +3 6066 3171 4119 +3 5389 3732 1971 +3 2330 481 2093 +3 320 1566 4003 +3 3347 3734 3880 +3 3880 3734 3735 +3 329 3735 7103 +3 5818 972 2865 +3 5309 6033 3795 +3 4109 4110 4685 +3 2328 4196 7107 +3 7103 3735 3733 +3 3532 3372 5156 +3 976 3780 1378 +3 348 3548 3866 +3 3548 3738 1377 +3 2556 3824 5623 +3 6148 5269 6795 +3 4398 3990 4003 +3 4145 3990 4398 +3 3701 5575 1123 +3 5897 3745 3215 +3 3215 3745 6631 +3 2908 85 2057 +3 3622 3748 5911 +3 4230 3753 4047 +3 4230 4047 1839 +3 3461 3464 2780 +3 5 3999 3990 +3 3756 4800 2429 +3 7138 985 708 +3 3383 2153 7219 +3 3757 6766 322 +3 6766 3757 602 +3 2265 652 3341 +3 4587 3758 6761 +3 6761 3758 1624 +3 3863 3759 4334 +3 4334 3759 3860 +3 2136 2231 3138 +3 1269 988 4431 +3 2566 4899 5050 +3 7431 3765 5984 +3 5984 7143 7431 +3 3205 5984 3765 +3 2604 4953 2768 +3 443 242 60 +3 4105 5989 1030 +3 3269 3768 5637 +3 5637 3768 2090 +3 2404 3769 3633 +3 3657 3658 3928 +3 2200 3770 4507 +3 3815 4974 3242 +3 1208 4244 4182 +3 3773 3193 3403 +3 1160 4892 1590 +3 3193 3773 4966 +3 3507 6312 6545 +3 2609 1702 4956 +3 1349 2643 1202 +3 2262 3780 2725 +3 1970 52 117 +3 2725 3780 2682 +3 6509 3782 7394 +3 3589 5239 4101 +3 1973 4529 5895 +3 1628 4099 398 +3 4899 4669 5050 +3 5895 588 1973 +3 1034 3783 5047 +3 3541 3785 524 +3 524 3785 3786 +3 3618 6431 3594 +3 4366 3786 3764 +3 3764 3786 3783 +3 1881 7473 6423 +3 963 3029 1956 +3 3251 3788 3094 +3 918 3789 3216 +3 3216 3789 2304 +3 5918 5224 2528 +3 1714 4506 5122 +3 4109 4003 1566 +3 3405 963 1956 +3 3760 3791 2000 +3 5934 6035 4670 +3 3791 2470 2305 +3 3792 1924 2630 +3 3826 4312 3793 +3 4260 6904 4098 +3 397 5034 6351 +3 15 4004 4081 +3 7035 7030 1009 +3 1914 4764 7225 +3 3311 3798 671 +3 4558 3799 4997 +3 3679 2265 3729 +3 3589 4101 4095 +3 4089 4090 17 +3 4997 3799 5411 +3 3190 3800 3289 +3 1530 3112 6662 +3 3112 1530 323 +3 1816 4715 3652 +3 2877 68 1953 +3 5922 5998 1777 +3 3331 3459 949 +3 323 3331 949 +3 4015 3804 1176 +3 3805 2641 1968 +3 1981 5633 5997 +3 932 3806 5359 +3 3806 63 673 +3 63 3806 3804 +3 328 3231 2205 +3 6790 3808 1218 +3 4085 4086 1264 +3 3782 3809 7394 +3 7394 3809 6177 +3 4045 3810 751 +3 591 4227 1824 +3 952 3811 2306 +3 4868 4088 4080 +3 4676 6847 6581 +3 298 2202 330 +3 330 2086 298 +3 175 3816 3818 +3 6945 3818 3819 +3 6945 3819 1707 +3 3819 6076 1856 +3 2749 1938 5576 +3 6076 3819 3816 +3 4166 3820 802 +3 7353 2265 7321 +3 4551 7492 7490 +3 4351 3821 4176 +3 4176 3821 7233 +3 292 4318 4263 +3 4962 3822 5977 +3 5388 3450 3021 +3 2309 869 2289 +3 1967 870 2053 +3 4228 1510 5625 +3 6636 4220 2709 +3 326 913 5440 +3 172 1472 4016 +3 1284 3824 331 +3 3979 2302 331 +3 5125 3793 4155 +3 5317 1323 369 +3 2863 6276 4991 +3 5116 5145 6297 +3 5116 2023 5145 +3 6588 7425 2722 +3 1608 5479 2025 +3 2175 5955 4176 +3 3023 3828 3608 +3 3318 3830 6895 +3 3318 6895 3394 +3 3017 3831 4524 +3 4800 3833 1029 +3 3068 1090 541 +3 1029 3833 5431 +3 1354 6373 363 +3 3831 3835 4668 +3 4668 3835 333 +3 3065 2559 336 +3 1445 5726 4074 +3 336 3839 3065 +3 6106 3839 3415 +3 3815 5338 4763 +3 333 3415 3839 +3 2642 3840 5528 +3 2380 2427 3991 +3 1313 1454 195 +3 4875 3842 538 +3 6474 538 1454 +3 6189 3843 4516 +3 2062 5542 1312 +3 3389 7105 4196 +3 3198 7476 3596 +3 1169 4041 4004 +3 3640 4881 2948 +3 4501 6996 5314 +3 7309 3848 5335 +3 4464 3849 4855 +3 4855 3849 3955 +3 879 3851 905 +3 905 3851 4927 +3 6241 1484 4803 +3 2628 4041 1169 +3 4027 2793 5558 +3 4064 4065 778 +3 3802 2800 2154 +3 3673 3855 6787 +3 5386 3856 5031 +3 5031 3856 7490 +3 3527 3528 3355 +3 4726 3857 3859 +3 345 3442 2591 +3 346 5743 122 +3 4058 4062 7187 +3 7243 6024 4635 +3 6211 6647 6355 +3 4431 988 358 +3 347 3207 4320 +3 341 3861 4860 +3 4057 5403 6391 +3 4981 3863 2626 +3 3863 349 2317 +3 571 3866 3548 +3 2203 3866 349 +3 349 4334 2203 +3 2809 3868 2470 +3 631 6163 3496 +3 3869 7392 2886 +3 7392 3869 1287 +3 3903 3871 4137 +3 1074 4501 1617 +3 3102 3872 938 +3 938 3872 4466 +3 6067 6458 3971 +3 3879 3873 713 +3 357 3874 3875 +3 3875 695 357 +3 6646 3875 6473 +3 6473 3875 3873 +3 6640 3876 1200 +3 4062 3877 7187 +3 5200 1294 3194 +3 3662 4763 5338 +3 7187 3877 7288 +3 2377 5639 5642 +3 1873 728 1505 +3 1115 3878 713 +3 2962 3879 4075 +3 4075 3879 4074 +3 3875 3881 695 +3 5017 7270 7385 +3 3405 1956 5166 +3 695 3881 5516 +3 5605 3882 7279 +3 7279 3882 4154 +3 6349 7492 4551 +3 7515 3469 4742 +3 5176 2914 921 +3 7179 5038 6116 +3 3884 5797 146 +3 5797 3884 5053 +3 338 3885 5675 +3 156 2566 6861 +3 5675 3885 4178 +3 3914 6589 2634 +3 2951 3887 1358 +3 1358 3887 3888 +3 6370 3888 1048 +3 1820 1048 372 +3 2984 3889 5869 +3 5869 3889 2149 +3 1965 2799 1994 +3 3693 4374 1887 +3 6513 152 7312 +3 4896 1660 3090 +3 3358 3892 6983 +3 6983 3892 1138 +3 2322 3894 1909 +3 1725 3137 5820 +3 1909 4534 2322 +3 5176 7179 3222 +3 5543 1758 1235 +3 3898 1447 5504 +3 1447 3898 2715 +3 4042 4043 4985 +3 851 5364 5112 +3 1997 4137 5616 +3 4137 3901 3903 +3 383 6719 2903 +3 2736 3903 3899 +3 2871 6661 5043 +3 3899 1883 2736 +3 2326 7173 5202 +3 5128 862 6020 +3 6236 7090 4031 +3 6232 3078 5317 +3 5298 7203 803 +3 2994 3905 2897 +3 2456 2488 2321 +3 5710 2488 2456 +3 3051 394 3486 +3 1602 3797 3051 +3 1396 3907 5989 +3 5989 3907 5736 +3 713 3874 1026 +3 86 3911 5929 +3 5929 3911 1794 +3 701 5280 844 +3 3914 2634 2986 +3 4030 591 540 +3 6589 3914 614 +3 2573 5985 3727 +3 3479 1263 6976 +3 614 3914 6716 +3 6248 3915 2341 +3 1190 1623 2734 +3 3605 3917 5347 +3 5347 1364 3605 +3 1642 3515 1654 +3 1640 4787 359 +3 6260 3918 3920 +3 197 4116 2915 +3 4086 3920 1784 +3 5632 3540 3651 +3 5000 3540 5632 +3 1784 1264 4086 +3 6057 3922 2971 +3 3924 2521 6547 +3 2521 3924 3965 +3 2124 3925 2199 +3 2199 3925 4128 +3 6112 3927 6754 +3 5277 3930 4885 +3 2779 5715 1894 +3 4885 3930 5489 +3 6032 6901 4485 +3 613 3910 4677 +3 694 896 3218 +3 6368 3935 4787 +3 4787 3935 359 +3 360 3935 6015 +3 7491 7492 259 +3 6898 4327 4285 +3 381 5872 2423 +3 1457 1950 3938 +3 3938 6130 142 +3 1950 7435 640 +3 2349 4877 4024 +3 1046 4021 4793 +3 5881 6319 5694 +3 62 5215 6901 +3 136 3941 2333 +3 3644 3942 3496 +3 4387 1186 3496 +3 1554 3198 1147 +3 5165 6990 7039 +3 5215 62 1715 +3 1420 4793 3 +3 750 2336 3944 +3 5698 5700 2598 +3 4478 3946 7291 +3 5835 3139 1639 +3 3946 523 407 +3 771 2909 5927 +3 7034 3947 4529 +3 623 6893 6892 +3 5034 4097 4018 +3 3948 5885 1097 +3 5885 3948 689 +3 3552 3949 688 +3 6250 2054 2497 +3 688 7374 3552 +3 2776 4569 2228 +3 3951 5024 1353 +3 4246 5024 3951 +3 6739 3952 2631 +3 2631 3952 6128 +3 6275 489 3636 +3 2486 3953 847 +3 2739 5276 2307 +3 5024 4246 4717 +3 3848 3849 5335 +3 4855 3955 4544 +3 5405 3957 7311 +3 1176 4987 4015 +3 1630 3958 4446 +3 4446 3958 2130 +3 6637 3535 189 +3 3352 3959 6721 +3 1893 7446 4602 +3 436 4562 1449 +3 3800 3960 3289 +3 2827 6875 7153 +3 3289 3960 3961 +3 4963 3961 479 +3 479 3961 3959 +3 1094 1096 3963 +3 2623 3636 489 +3 4135 4150 2132 +3 1054 839 4189 +3 488 3966 1093 +3 6346 3967 5283 +3 950 4135 1143 +3 7153 7114 70 +3 3962 1683 2369 +3 1475 3969 536 +3 3295 3970 2519 +3 2519 3970 5452 +3 6129 5708 825 +3 6149 3973 6735 +3 4330 4961 3532 +3 6735 3973 4666 +3 5773 3975 6968 +3 6968 3975 4242 +3 4880 5135 6088 +3 5976 2724 2465 +3 6355 945 4027 +3 3226 3016 7239 +3 3977 6191 987 +3 2354 3978 6687 +3 5934 4104 4330 +3 901 3980 6125 +3 3018 3631 469 +3 247 6425 1091 +3 489 3631 3018 +3 6425 3980 1173 +3 1338 4150 2133 +3 2732 6178 1001 +3 7213 3986 2267 +3 902 3987 2714 +3 7182 4150 1338 +3 778 4065 4008 +3 370 4217 2356 +3 190 887 1426 +3 1489 3197 418 +3 6276 761 959 +3 374 686 2862 +3 5203 3995 1356 +3 4576 656 5863 +3 1356 3995 4448 +3 1222 4057 6391 +3 2585 1026 1027 +3 4738 4217 1198 +3 2909 872 5927 +3 379 5982 4692 +3 3779 4480 1843 +3 382 4052 7237 +3 3662 4589 915 +3 4792 4052 382 +3 5113 754 4550 +3 6459 859 5127 +3 1981 5997 667 +3 2128 14 4161 +3 1045 2571 6789 +3 713 1026 1115 +3 5427 5675 2991 +3 5068 5078 2615 +3 5805 3645 1117 +3 6836 160 6503 +3 5451 4400 1769 +3 2431 4007 3974 +3 2294 2235 5760 +3 3974 4007 5490 +3 1468 4008 2767 +3 2999 1733 6364 +3 4000 955 684 +3 6364 1733 4012 +3 2130 4161 59 +3 4336 4013 138 +3 849 6247 6329 +3 138 4013 5931 +3 2129 3958 3230 +3 4014 2295 3500 +3 4124 7409 289 +3 4104 4961 4330 +3 1609 1709 6069 +3 5309 6875 2827 +3 849 6329 7415 +3 4414 4305 4660 +3 2972 4015 3776 +3 1831 4281 589 +3 3775 5199 586 +3 4901 4018 3739 +3 1386 1042 877 +3 877 4097 562 +3 5959 4214 6048 +3 4240 3320 1024 +3 5502 1900 387 +3 4221 4022 2975 +3 3128 4024 4850 +3 1713 5280 2564 +3 3154 4030 1403 +3 1403 1472 3154 +3 2561 4031 3133 +3 4252 4032 7380 +3 4032 7090 2221 +3 390 2189 5021 +3 391 3006 4601 +3 2494 7111 7109 +3 5090 4042 4985 +3 5184 4043 7124 +3 7124 4043 4044 +3 432 4463 1197 +3 913 4044 5440 +3 5440 4044 4042 +3 3986 4917 3146 +3 3577 4045 6110 +3 499 5045 3984 +3 6110 4045 392 +3 5820 3137 5884 +3 6191 3977 901 +3 1138 4046 6983 +3 4651 2616 4601 +3 6314 4046 751 +3 2238 4854 2819 +3 392 751 4046 +3 1412 1424 2589 +3 3753 5081 3000 +3 529 1839 4839 +3 2997 4242 3976 +3 1574 3636 7457 +3 1472 2829 4016 +3 5675 4178 2991 +3 298 4666 3972 +3 5956 6481 2728 +3 7457 3636 615 +3 3969 5536 5453 +3 4823 4054 871 +3 4932 4633 5278 +3 871 4054 5551 +3 5624 4055 6031 +3 1446 4620 4057 +3 6211 5558 7046 +3 3476 4058 7187 +3 3326 4062 3796 +3 7520 4010 1916 +3 3796 4062 4063 +3 4332 4063 807 +3 676 561 1584 +3 807 4063 4058 +3 3477 4064 778 +3 4008 4012 2767 +3 6364 4065 4069 +3 5707 4762 5809 +3 3528 4069 3355 +3 3355 4069 4064 +3 3710 3708 3919 +3 5238 4070 6188 +3 4071 1311 1317 +3 3051 4073 394 +3 3963 2005 1848 +3 6186 3994 394 +3 3878 3879 713 +3 4622 4075 3107 +3 3107 4075 5726 +3 3035 5643 1076 +3 16 4269 4316 +3 4267 4079 6889 +3 6187 4080 925 +3 7515 4742 2438 +3 3089 3088 3305 +3 3959 3960 6721 +3 5651 4084 4088 +3 1580 4085 1264 +3 2129 3230 6576 +3 4701 4544 3957 +3 3056 4086 4868 +3 4868 4086 4085 +3 4080 4084 925 +3 4857 5316 4649 +3 4088 4085 395 +3 1317 6128 3953 +3 4874 4089 17 +3 3567 4090 5368 +3 5368 4090 4091 +3 396 4091 3155 +3 3624 2829 1472 +3 2360 3951 3161 +3 3572 808 405 +3 3155 4091 4089 +3 4024 4094 2349 +3 5201 5243 708 +3 4285 5888 7200 +3 2349 4094 4101 +3 5878 3989 895 +3 2332 4096 5367 +3 6710 5367 1546 +3 7095 7111 4569 +3 4018 4019 3739 +3 562 1386 877 +3 2358 3457 3340 +3 3340 6904 3364 +3 2037 4099 4100 +3 5189 4100 4061 +3 4061 4100 6596 +3 4220 2441 2709 +3 2430 3949 6138 +3 3984 5008 499 +3 4095 4094 5878 +3 4779 4102 3558 +3 3558 4102 5239 +3 3430 3379 3425 +3 3467 4103 5520 +3 2698 4105 4103 +3 1496 1083 7415 +3 4529 3947 4568 +3 4117 3850 4580 +3 1496 4106 7107 +3 4107 4202 7106 +3 4202 4107 6270 +3 3944 2061 4442 +3 670 3074 1706 +3 5865 4387 3941 +3 6354 2948 7119 +3 4887 5206 6903 +3 4268 4109 4685 +3 3674 4110 5161 +3 6319 69 6318 +3 5161 4110 4111 +3 3734 4111 1566 +3 2803 4232 5159 +3 1566 4111 4109 +3 1731 1567 5532 +3 2319 1193 2422 +3 5544 5548 399 +3 7391 7389 1149 +3 7510 2916 7514 +3 5997 2982 667 +3 595 4113 3701 +3 6046 4113 400 +3 4114 383 400 +3 2740 5692 1557 +3 3449 3105 3142 +3 5840 4114 446 +3 1727 2968 3383 +3 4203 4115 4445 +3 4445 4115 402 +3 3338 3337 1548 +3 2332 5367 3337 +3 3401 6800 4096 +3 2699 2523 4599 +3 403 4115 3261 +3 2234 4119 3171 +3 2458 4128 3927 +3 6773 3191 4996 +3 416 5207 4167 +3 5207 4121 4122 +3 1059 450 4041 +3 6305 3628 944 +3 2408 4122 3248 +3 4269 2935 12 +3 3248 4122 4120 +3 7012 7334 293 +3 6654 6617 263 +3 4027 6211 6355 +3 2249 4048 2578 +3 4318 1799 2889 +3 7488 7487 199 +3 3895 4319 4355 +3 3814 6842 5146 +3 2818 3918 221 +3 2978 4374 4359 +3 3128 4125 5878 +3 2469 4126 2471 +3 2471 4126 6107 +3 3927 3925 6754 +3 4753 6517 3709 +3 3855 4130 4551 +3 4551 4130 6352 +3 3537 4131 1067 +3 1908 1014 2812 +3 1908 1473 1014 +3 3271 4132 3170 +3 4494 7139 3134 +3 6134 6127 158 +3 3170 4132 5273 +3 3482 3483 3382 +3 1640 4134 4787 +3 4129 1275 2885 +3 4787 4134 6367 +3 3551 4148 4123 +3 1590 4127 1160 +3 407 7291 3946 +3 3169 4138 1401 +3 406 3711 4543 +3 2336 3711 406 +3 5342 4319 3895 +3 6294 5347 3915 +3 566 4154 3882 +3 6771 4140 4141 +3 2603 5744 3254 +3 4321 4141 1035 +3 1035 4141 5465 +3 4142 4183 166 +3 436 3774 4124 +3 4265 4144 4398 +3 2822 3911 5857 +3 3008 4145 5840 +3 5840 4145 1949 +3 4626 3157 186 +3 4123 3572 405 +3 3950 5342 6909 +3 6541 4149 2270 +3 2270 4149 1345 +3 5837 5836 3728 +3 3110 4343 4319 +3 4005 6504 4119 +3 885 4151 1035 +3 410 580 2648 +3 4783 580 2209 +3 562 680 1386 +3 1292 4555 5100 +3 2771 6652 7203 +3 4965 4152 2629 +3 2629 4152 4293 +3 5449 5675 5427 +3 4954 4153 5583 +3 412 6454 6311 +3 5532 4599 2523 +3 412 6091 6454 +3 2339 5967 797 +3 5808 6020 1100 +3 5302 4157 1479 +3 1479 4157 6650 +3 6537 5871 6267 +3 1077 2748 5657 +3 3322 5858 5152 +3 2730 5736 3908 +3 4013 4158 7344 +3 7344 4158 4579 +3 5504 6197 3898 +3 6965 4579 4158 +3 592 868 3061 +3 868 430 3061 +3 3266 4164 431 +3 798 3905 7009 +3 431 4548 3266 +3 5237 5712 1424 +3 1537 6078 413 +3 413 2343 1537 +3 7208 4343 3110 +3 1168 6859 1691 +3 3603 4502 2156 +3 676 1584 4165 +3 3073 6030 862 +3 6222 4165 3719 +3 3899 3901 5364 +3 3820 3564 4338 +3 1502 2168 3011 +3 1956 3325 3913 +3 1502 4167 4168 +3 6962 4168 802 +3 802 4168 4166 +3 6069 6848 852 +3 4171 3421 5432 +3 7482 7483 6428 +3 5089 3517 3634 +3 4082 2514 2701 +3 3828 4172 3608 +3 3604 4173 5049 +3 5147 7138 628 +3 5049 4173 4174 +3 2913 5544 4213 +3 4473 4174 5216 +3 5216 4174 4172 +3 2904 3247 5450 +3 4165 4222 676 +3 4213 4359 2913 +3 5237 3427 485 +3 7001 4175 6084 +3 5146 4175 7280 +3 3817 6806 2127 +3 7280 4175 2115 +3 6887 4177 6830 +3 3596 5156 340 +3 2912 6585 2125 +3 3243 4275 4178 +3 5053 4178 3578 +3 2190 5123 637 +3 4010 7066 4201 +3 637 6214 5043 +3 418 7248 3212 +3 7248 4181 6717 +3 2731 4184 343 +3 6238 3661 1972 +3 5975 6699 2958 +3 3116 5312 5221 +3 2090 420 5637 +3 481 2239 6 +3 4185 481 6 +3 2125 4389 2912 +3 5674 1799 4083 +3 2115 1515 5362 +3 4192 4193 4365 +3 4365 7401 4192 +3 2759 4396 5098 +3 2277 4193 1199 +3 1199 4193 4190 +3 1731 5494 5803 +3 6893 4325 3741 +3 1621 2395 2353 +3 5532 5494 1731 +3 2530 1576 3285 +3 6188 4198 1017 +3 1017 4198 4798 +3 3344 6197 5504 +3 7084 4199 6988 +3 3836 4232 2803 +3 4199 287 5576 +3 426 4200 841 +3 4115 3270 3261 +3 4891 829 553 +3 4206 297 1478 +3 841 297 4206 +3 1824 540 591 +3 2126 4389 753 +3 1138 3892 4964 +3 2171 5392 6111 +3 1161 6065 427 +3 6959 5693 428 +3 5449 5336 338 +3 428 4208 6959 +3 1777 4853 5922 +3 4277 3406 5267 +3 6126 4208 6687 +3 6687 4208 2354 +3 399 790 5544 +3 4213 5138 4727 +3 338 5675 5449 +3 4969 5138 790 +3 3061 430 431 +3 431 433 4548 +3 1154 2878 1441 +3 4215 4738 5229 +3 4217 4738 433 +3 432 3987 4463 +3 2356 2714 370 +3 2562 3887 6511 +3 4399 4218 501 +3 3656 5428 3886 +3 2975 6939 4078 +3 2975 4219 4221 +3 7216 4221 4730 +3 447 381 7303 +3 4730 4221 4218 +3 6754 3925 2126 +3 437 3534 2196 +3 4209 4223 6828 +3 1947 4224 3142 +3 1172 4226 591 +3 591 4226 4227 +3 3998 4435 4424 +3 2830 4227 5701 +3 5701 4227 4224 +3 6553 2495 1734 +3 4620 5875 3629 +3 3487 4229 7390 +3 667 225 3522 +3 828 4229 6677 +3 7390 4229 529 +3 4231 3343 934 +3 2123 5500 4425 +3 6032 4545 4939 +3 6237 4233 5461 +3 5461 4233 5297 +3 3013 7320 5493 +3 1690 7320 3013 +3 4972 4234 2517 +3 2517 4234 1667 +3 4394 4235 2708 +3 3505 3746 2346 +3 5811 4364 4804 +3 2708 4235 4436 +3 4019 4236 3739 +3 3856 4238 6787 +3 6787 4238 6180 +3 5100 4239 1292 +3 6091 4239 7110 +3 180 4425 5500 +3 3578 4178 3885 +3 916 921 7002 +3 4237 4240 1213 +3 2974 4241 2997 +3 4241 440 4242 +3 3976 3975 2802 +3 4376 2244 7088 +3 6968 4242 2357 +3 2298 4241 3201 +3 8 5620 7506 +3 442 7195 8 +3 4178 5053 3243 +3 912 4247 1108 +3 2878 6116 5038 +3 1358 3888 821 +3 1358 821 593 +3 5509 4400 6487 +3 3290 3096 4283 +3 1818 824 592 +3 2120 4425 2122 +3 3728 3714 2808 +3 3221 4250 5668 +3 3343 5811 4804 +3 5668 4250 6827 +3 3298 4252 5844 +3 602 5437 6766 +3 4253 4821 1811 +3 4821 4253 1002 +3 446 3008 5840 +3 4254 449 2361 +3 952 3138 2231 +3 952 2231 4255 +3 449 3701 4256 +3 1854 2773 2120 +3 4798 4257 241 +3 3227 4258 5948 +3 3882 1401 566 +3 5948 4258 5801 +3 1892 4262 508 +3 2934 4264 7277 +3 7277 7229 2934 +3 2540 4321 7146 +3 4903 4265 5760 +3 2413 4266 4685 +3 4685 4266 4268 +3 5480 6275 1574 +3 1526 1697 3709 +3 1412 2589 1766 +3 4003 4268 4398 +3 3855 3856 6787 +3 4398 4268 4265 +3 3194 1294 6749 +3 456 6383 1954 +3 4074 3878 386 +3 4949 6685 1853 +3 1196 4270 1679 +3 3876 2242 151 +3 4632 5281 7127 +3 2893 1799 5674 +3 1427 2597 1190 +3 3934 3929 1056 +3 1574 4082 2701 +3 3873 3874 713 +3 7229 4469 2123 +3 4271 1107 2943 +3 1107 4271 1679 +3 458 4170 752 +3 6069 4273 1609 +3 6906 7299 6869 +3 2991 4275 4751 +3 3852 4404 1506 +3 459 5689 6341 +3 459 1340 5689 +3 3727 2724 5976 +3 5068 863 4476 +3 2757 5973 176 +3 4278 1215 2750 +3 2750 1028 4278 +3 6830 7104 7112 +3 6830 4177 4279 +3 4520 4279 4284 +3 6830 4279 2737 +3 7329 7488 1120 +3 4565 4466 3871 +3 460 1813 5303 +3 1287 928 6163 +3 1813 4280 1605 +3 1799 2893 3363 +3 6860 4048 5876 +3 5927 872 756 +3 3775 4281 910 +3 892 4286 1234 +3 1234 5094 892 +3 4733 3540 3675 +3 316 7487 4316 +3 1551 4288 2164 +3 793 3675 816 +3 2317 2626 3863 +3 1428 2251 4602 +3 1111 3191 3771 +3 4411 7336 2769 +3 1595 4289 2008 +3 4289 2904 6401 +3 4842 4290 5960 +3 5410 4291 4997 +3 4997 4291 4556 +3 4292 1837 5857 +3 5214 5235 5907 +3 4153 4152 5583 +3 2000 4860 3860 +3 3190 4295 3313 +3 3313 4295 4391 +3 344 1398 5746 +3 4566 5694 2386 +3 4300 6302 1863 +3 6302 4300 5590 +3 3266 4301 3182 +3 3182 4301 6689 +3 1547 4302 3904 +3 914 4302 4348 +3 4497 4304 6865 +3 3434 1963 775 +3 4177 4308 4307 +3 6068 4309 2780 +3 6108 4310 2471 +3 2471 4310 5457 +3 4077 454 5408 +3 6324 1361 4311 +3 4288 4313 4835 +3 4835 165 4288 +3 6995 4314 4834 +3 4834 4314 6961 +3 1958 6341 5689 +3 2419 4483 4517 +3 1210 696 2800 +3 4854 1791 1786 +3 1088 1721 1541 +3 462 461 1088 +3 7248 5162 903 +3 6227 4317 3494 +3 6825 3494 2763 +3 2159 4483 2419 +3 4551 7490 3855 +3 1035 4151 4321 +3 6247 5863 6329 +3 6085 5470 4690 +3 1317 3953 4071 +3 2864 6135 4322 +3 4211 4495 4731 +3 717 4323 1785 +3 3741 4325 4327 +3 4285 4327 5888 +3 3134 846 2045 +3 5888 4327 2653 +3 5712 5237 5585 +3 3427 5237 1424 +3 2851 1955 6464 +3 3651 6336 5032 +3 354 6495 6726 +3 6981 4491 4483 +3 6431 3618 7204 +3 6536 4331 807 +3 4063 2969 3796 +3 7311 3955 3848 +3 7475 4332 6023 +3 2438 4742 2876 +3 6231 3371 271 +3 6965 4158 4336 +3 498 3755 6427 +3 2114 6113 893 +3 2315 1320 6226 +3 6226 3494 2315 +3 5371 2536 1332 +3 5149 2285 2705 +3 2313 421 251 +3 4517 5004 971 +3 369 7466 999 +3 3368 4337 5960 +3 3626 4396 7058 +3 3145 7010 3228 +3 2472 5441 1032 +3 4337 1451 883 +3 3264 5035 1195 +3 3264 4342 6714 +3 5253 960 4005 +3 2512 5574 2787 +3 4646 1052 6872 +3 6872 3646 4646 +3 4941 4344 3195 +3 3195 4344 7152 +3 6097 4345 786 +3 2885 2421 4129 +3 2368 2371 930 +3 2555 930 2371 +3 4349 787 1720 +3 787 4349 2707 +3 1263 3479 5433 +3 333 1038 4668 +3 5955 4351 4176 +3 6725 4351 4624 +3 3831 4668 5425 +3 4918 94 5243 +3 6233 7487 316 +3 2108 5113 4550 +3 2428 6895 3829 +3 2500 4352 2274 +3 5516 5517 695 +3 2274 4352 5714 +3 3852 4406 3998 +3 4353 4711 4151 +3 4711 4353 5714 +3 6301 6967 2557 +3 2821 6857 6121 +3 2167 4356 1224 +3 1224 4156 2167 +3 3928 4357 472 +3 472 6003 1223 +3 2472 5550 3828 +3 473 5092 2113 +3 473 719 5092 +3 5054 4360 5453 +3 3269 5637 2513 +3 4326 639 3473 +3 2502 4362 5996 +3 5470 5068 2615 +3 5996 4362 2582 +3 1801 6409 3405 +3 2375 4363 7262 +3 3502 4366 475 +3 4628 3248 475 +3 891 4367 4315 +3 3951 6304 3161 +3 5125 5586 3826 +3 4315 4367 4370 +3 5586 5125 4441 +3 2101 4368 7262 +3 3479 1466 1132 +3 7262 4368 2375 +3 5421 6571 6495 +3 3369 3371 6231 +3 478 2005 1237 +3 2005 4372 1845 +3 3220 5042 7418 +3 5815 3099 490 +3 6104 4975 3823 +3 4974 1162 1391 +3 2051 3237 7048 +3 858 2109 4578 +3 4441 4460 3602 +3 5248 923 4377 +3 2515 3158 7417 +3 2961 1407 968 +3 5498 5747 2250 +3 3905 4379 7009 +3 3480 3481 2834 +3 2393 4443 2555 +3 5681 4594 2859 +3 1493 4595 4725 +3 2994 2686 4379 +3 2898 3582 6552 +3 3010 4818 2409 +3 3393 6034 4984 +3 2255 496 3997 +3 3417 6561 3822 +3 496 5365 3997 +3 1288 5704 6169 +3 3686 4881 7433 +3 4699 631 4386 +3 2297 4386 1187 +3 5521 6437 7364 +3 3941 3942 2333 +3 3496 3942 4387 +3 5679 2521 5596 +3 7169 4388 82 +3 82 4388 990 +3 4338 6488 3820 +3 6982 4635 5761 +3 3767 4656 1357 +3 287 990 4305 +3 3896 7126 75 +3 3818 3149 175 +3 75 1573 3896 +3 330 3811 2086 +3 2861 2257 5850 +3 981 5502 503 +3 4293 4295 2629 +3 4392 3313 4391 +3 5945 4392 1024 +3 1024 3320 5945 +3 4900 4394 2896 +3 3485 3278 5708 +3 2048 6177 3810 +3 6315 4395 4397 +3 6175 4397 2708 +3 2708 4397 4394 +3 504 6776 1579 +3 3047 4399 501 +3 1078 3921 2737 +3 2691 6266 4908 +3 3483 4402 3382 +3 5815 2376 1217 +3 4448 4405 6883 +3 1176 3804 932 +3 3152 4443 2393 +3 6151 4407 361 +3 361 4407 4408 +3 3046 4408 5134 +3 5134 4408 4405 +3 5343 5757 2563 +3 3414 4409 7358 +3 505 3779 2015 +3 505 4479 3779 +3 4786 5415 3800 +3 3348 5607 1133 +3 6886 5411 3798 +3 506 5683 4973 +3 2385 2622 826 +3 2102 4914 5847 +3 5226 4415 5492 +3 6202 4416 2985 +3 2985 4416 5636 +3 4808 4809 2473 +3 3245 1961 5752 +3 1314 4417 4418 +3 804 7151 4525 +3 4682 4795 7015 +3 3692 4418 1402 +3 1402 4418 4725 +3 2754 4420 512 +3 512 6166 2754 +3 2304 4423 3216 +3 3216 4423 510 +3 1252 1404 514 +3 514 4420 1252 +3 2834 2979 1016 +3 4426 327 3507 +3 327 4426 6475 +3 702 4427 85 +3 85 4427 6475 +3 5991 1797 6763 +3 4966 2680 5613 +3 4429 4237 1213 +3 6774 6726 4812 +3 4237 4429 517 +3 3521 5563 2687 +3 515 7075 5941 +3 4433 2921 3233 +3 2920 7470 3591 +3 6172 2420 3234 +3 3571 6389 4318 +3 517 658 4433 +3 1691 4873 1168 +3 4236 4235 3739 +3 6287 6265 2252 +3 2115 5362 6797 +3 7425 5057 1090 +3 518 6174 6175 +3 7374 688 689 +3 520 1291 7374 +3 4439 2093 2983 +3 2470 3791 2809 +3 1174 6051 2570 +3 4312 3826 6607 +3 522 2061 6441 +3 7450 2883 5619 +3 6301 5443 3303 +3 525 4403 4422 +3 4350 4450 546 +3 4444 4442 1429 +3 1976 5568 756 +3 2033 6868 4143 +3 4405 3995 5134 +3 1356 4448 5217 +3 4567 4449 4350 +3 546 3062 4506 +3 3062 4450 6376 +3 5744 5767 2630 +3 4533 5279 87 +3 3042 464 3304 +3 44 4315 4370 +3 5533 3600 508 +3 3012 6743 2855 +3 146 3788 3884 +3 3598 4452 1444 +3 4453 5368 396 +3 5368 4453 4454 +3 4191 4454 4452 +3 2465 2724 2688 +3 851 528 1883 +3 6485 4456 7201 +3 2555 4443 2887 +3 4458 7201 528 +3 1079 4244 1208 +3 4458 2096 3037 +3 4546 4462 4855 +3 6746 4464 5483 +3 5483 4464 5890 +3 3880 3735 632 +3 4239 5100 3593 +3 415 4644 2906 +3 7385 703 5017 +3 3871 3872 4137 +3 938 4466 533 +3 7131 4467 4746 +3 3783 3785 5047 +3 4746 4467 2391 +3 534 4565 1529 +3 4568 5895 4529 +3 534 4466 4565 +3 4024 4471 4850 +3 5551 4472 5216 +3 5216 4472 4473 +3 4174 3315 5049 +3 2218 4473 4471 +3 3347 4474 5161 +3 4552 6317 3782 +3 6940 2803 5159 +3 2682 3780 976 +3 7351 4475 5148 +3 5148 4475 6731 +3 6963 6894 5909 +3 1394 1696 5499 +3 3655 4477 6294 +3 6294 4477 969 +3 6441 4478 1407 +3 2062 1312 4272 +3 1407 4478 968 +3 2384 5683 506 +3 1843 4480 2264 +3 1051 4480 4640 +3 2544 6817 2534 +3 3460 4481 4703 +3 3722 3724 5524 +3 6053 4644 415 +3 6313 3681 1722 +3 1183 4482 4434 +3 881 4222 4165 +3 4482 2392 1504 +3 2729 4481 5832 +3 5832 1507 2729 +3 677 3616 997 +3 7322 3954 5919 +3 4488 5730 2774 +3 6411 6409 4840 +3 6623 4489 1788 +3 3077 2338 2258 +3 4488 4489 1877 +3 2680 4966 3777 +3 2331 3183 6882 +3 7418 5042 7348 +3 2100 4644 7218 +3 3179 1864 3265 +3 6093 3314 7251 +3 1443 4490 5972 +3 6586 4674 2719 +3 5122 4507 3769 +3 2996 4220 6004 +3 5972 4490 2022 +3 2090 3768 2983 +3 1956 3029 3325 +3 577 6747 6626 +3 540 543 1403 +3 2099 2100 6888 +3 3698 3010 1761 +3 7243 6033 6024 +3 4862 4497 341 +3 3213 626 4984 +3 2000 3860 3760 +3 4497 4498 3533 +3 5991 4443 3152 +3 1905 4822 1144 +3 4498 6865 5922 +3 3016 4499 7239 +3 2426 4500 1736 +3 1736 4500 5404 +3 2506 6935 7145 +3 7228 3516 1462 +3 4503 1522 1153 +3 5221 5048 3116 +3 3916 3236 1633 +3 2101 7262 5141 +3 4687 4728 7063 +3 5008 6834 499 +3 3730 3993 5259 +3 1327 4505 4320 +3 6926 1624 3758 +3 6168 4505 88 +3 3079 2607 2664 +3 2524 6287 3436 +3 6277 6935 2506 +3 6763 2996 6004 +3 602 880 4647 +3 181 4693 4687 +3 88 4505 2673 +3 6165 6152 92 +3 831 3022 5784 +3 3769 3770 3633 +3 3833 4800 4524 +3 2200 4507 4509 +3 1406 4509 3062 +3 4340 3755 4830 +3 3062 4509 4506 +3 636 4511 6035 +3 6035 4511 4670 +3 1261 4047 3749 +3 7156 6631 3748 +3 5955 2155 3723 +3 194 4513 1746 +3 1746 4536 194 +3 2692 3738 4320 +3 2815 4514 492 +3 492 4514 6955 +3 225 667 2982 +3 7076 4515 81 +3 6189 4516 7300 +3 1814 2816 6192 +3 2359 548 4066 +3 548 6088 4066 +3 973 4521 2727 +3 2727 4521 6985 +3 5912 4522 7214 +3 643 4308 1621 +3 3452 6794 3771 +3 5850 7486 2861 +3 2273 4526 1717 +3 1717 4526 5631 +3 4528 5688 137 +3 3346 3183 2331 +3 1496 3845 3372 +3 4867 6710 1546 +3 7034 4529 6892 +3 1901 5377 6668 +3 6005 7341 2617 +3 3733 3734 1566 +3 55 7014 6935 +3 6641 6653 2137 +3 6800 3401 5831 +3 6247 4104 4670 +3 4693 181 2901 +3 4573 4476 6404 +3 4573 4533 6383 +3 6999 3619 4535 +3 6888 4728 2099 +3 7211 5137 4535 +3 172 7270 2764 +3 2544 4535 3619 +3 5146 7280 6676 +3 676 2188 561 +3 2299 2645 733 +3 6419 6793 560 +3 560 4537 6419 +3 4537 3945 278 +3 561 3945 4537 +3 2340 4538 6667 +3 3556 5311 3555 +3 6351 2527 563 +3 4577 3665 4559 +3 275 2377 5662 +3 4557 4540 4830 +3 7317 7017 1859 +3 4304 6487 5762 +3 3201 5351 2298 +3 3824 3048 5623 +3 3203 281 3123 +3 1953 870 2877 +3 1509 4543 3711 +3 2339 4543 5967 +3 7063 7064 2799 +3 5967 4543 983 +3 846 3134 4092 +3 4966 5613 3535 +3 5493 7320 162 +3 2878 5038 1966 +3 3957 3955 7311 +3 6038 6993 708 +3 1642 1654 3954 +3 4612 4546 3462 +3 3462 4546 4990 +3 5994 7353 6505 +3 567 4555 1292 +3 6487 4400 5762 +3 3996 2497 4943 +3 1861 111 3790 +3 111 1861 2870 +3 3388 4555 6148 +3 4290 4291 5960 +3 3353 4558 3497 +3 3497 4558 4791 +3 3100 3101 668 +3 6649 4697 4272 +3 6115 5597 3290 +3 5903 6969 1918 +3 572 679 3101 +3 2447 3183 3346 +3 5760 4266 2413 +3 172 6463 2537 +3 2317 4564 2626 +3 5685 4564 2364 +3 570 2364 4564 +3 1111 3071 3191 +3 5188 2718 3448 +3 6969 5903 5163 +3 5324 4567 2104 +3 1225 4778 2905 +3 1708 6193 2228 +3 5943 7085 4376 +3 2228 4569 1708 +3 656 6270 4107 +3 5476 730 2813 +3 4996 3191 3071 +3 3114 703 889 +3 3905 3906 2897 +3 2460 4571 2531 +3 2531 4571 4572 +3 2788 4778 1225 +3 3256 2193 6096 +3 6795 5269 2980 +3 1568 798 7009 +3 856 5478 1533 +3 2336 750 3711 +3 1797 7428 92 +3 6148 4547 5269 +3 3151 844 3147 +3 3151 966 3416 +3 2446 4575 967 +3 967 1329 2446 +3 3718 4795 5422 +3 196 2772 7185 +3 1077 498 6427 +3 498 4582 4852 +3 1253 6391 5403 +3 1899 2676 6846 +3 3717 7032 7327 +3 4557 4830 4852 +3 3402 4585 2325 +3 5757 4341 3121 +3 6919 4586 3617 +3 7256 5353 2862 +3 5214 7069 5236 +3 3617 4586 5173 +3 4587 6761 1755 +3 3758 2930 3377 +3 2597 1436 882 +3 4588 383 4114 +3 383 4588 6719 +3 5320 5906 5918 +3 5862 4794 2097 +3 575 3045 2276 +3 7078 1953 68 +3 2292 4614 1116 +3 6546 1081 5659 +3 6310 4794 5862 +3 2403 126 1081 +3 6538 3384 1087 +3 6388 4596 1220 +3 1368 4597 1088 +3 1088 4597 4598 +3 1883 3899 851 +3 4577 1729 1730 +3 1719 4598 2103 +3 2103 4598 4596 +3 6389 3571 3713 +3 1290 4600 4603 +3 4603 516 1290 +3 6620 4603 5005 +3 2022 4604 5972 +3 5972 4604 582 +3 2293 1876 2291 +3 772 4070 3710 +3 3700 3703 2206 +3 7117 6249 321 +3 2977 22 276 +3 3633 4605 2404 +3 6289 3454 583 +3 1194 4802 4870 +3 583 4604 577 +3 2288 4607 3064 +3 3064 4607 587 +3 605 4608 2405 +3 7004 5703 3705 +3 2405 6580 605 +3 3697 976 1378 +3 586 4281 3775 +3 589 4607 1831 +3 4015 4610 3776 +3 3330 4611 3462 +3 1962 4802 1194 +3 6797 5362 1095 +3 3462 4611 4612 +3 2870 1861 6934 +3 4462 4612 6469 +3 3209 4825 4802 +3 6469 4612 4610 +3 3988 4656 6704 +3 1256 4613 3669 +3 3669 4613 980 +3 5381 7354 2849 +3 7472 4825 3209 +3 4322 4618 2864 +3 3886 4619 1725 +3 3034 6720 3695 +3 2867 3087 457 +3 2837 1683 2542 +3 3457 3458 4884 +3 2132 7182 1808 +3 4870 2511 1983 +3 3693 3817 2127 +3 739 6602 3692 +3 4623 3271 3170 +3 3688 3689 4527 +3 2358 4623 4621 +3 7454 4628 1945 +3 6697 4625 1726 +3 1726 4625 5331 +3 574 5331 4625 +3 598 7454 1387 +3 4883 4648 2355 +3 596 4366 3764 +3 3248 4628 2408 +3 6061 3685 3117 +3 4338 3564 2407 +3 3089 4631 925 +3 5955 7096 2155 +3 925 4631 6190 +3 5781 1339 2887 +3 3516 4636 205 +3 2355 33 4883 +3 3577 6110 3005 +3 2048 4637 6453 +3 3501 650 2988 +3 6067 1894 5715 +3 758 1336 738 +3 304 3678 7290 +3 4234 4639 993 +3 993 4639 4718 +3 664 5166 2831 +3 4479 4480 3779 +3 1051 4640 601 +3 1548 4641 3680 +3 6035 5934 6671 +3 3291 4641 600 +3 600 4796 216 +3 3156 3127 1448 +3 4128 4643 2199 +3 7484 1466 3479 +3 2199 4643 5817 +3 550 5633 7407 +3 4185 4871 481 +3 6287 5473 3436 +3 1002 4647 4821 +3 5166 664 2587 +3 4821 4647 875 +3 1210 783 3176 +3 616 7241 4824 +3 4652 1398 7293 +3 632 4653 3880 +3 5903 7004 3705 +3 1067 4130 3673 +3 4474 4655 5630 +3 5630 4655 7161 +3 3444 4659 3985 +3 4907 4658 3447 +3 3985 5814 3444 +3 3985 4659 5435 +3 2828 5723 3801 +3 720 3064 587 +3 2414 4662 4694 +3 4858 4694 720 +3 5875 4620 1446 +3 2089 4439 521 +3 608 7314 7181 +3 608 731 2087 +3 1909 1910 4534 +3 3168 4664 42 +3 42 4664 607 +3 3972 3973 5430 +3 6735 4666 2411 +3 611 2086 5749 +3 131 3176 783 +3 611 298 2086 +3 3069 5856 4496 +3 3554 4991 6861 +3 3383 2790 1727 +3 826 4669 2385 +3 1164 4512 3045 +3 2050 4671 1543 +3 7383 2434 4832 +3 1543 4671 1674 +3 1456 4972 2517 +3 409 697 6268 +3 4040 6877 1615 +3 1313 7376 6217 +3 7376 4675 5295 +3 6676 7280 5061 +3 4676 195 3238 +3 4749 2271 3583 +3 7370 6282 1936 +3 7370 4678 4679 +3 4805 4679 3910 +3 4083 6389 3365 +3 3910 4679 4677 +3 4599 6977 2619 +3 1694 674 5938 +3 7115 4681 5600 +3 5600 31 4958 +3 7407 6549 3825 +3 6941 4911 4906 +3 4683 5467 1569 +3 3378 7251 3314 +3 5467 4683 4619 +3 3825 550 7407 +3 1725 4619 4406 +3 5816 5099 1134 +3 6860 80 5178 +3 4110 4684 4685 +3 4684 618 2413 +3 6549 6664 3825 +3 617 4686 1630 +3 7425 3236 800 +3 944 3628 6957 +3 2775 4686 618 +3 618 7190 2775 +3 5633 550 4566 +3 6123 2293 3715 +3 2293 5703 7004 +3 3919 3708 777 +3 6095 4911 6941 +3 625 5982 1418 +3 2165 4692 4428 +3 4639 4972 1336 +3 2440 624 2414 +3 355 2730 3908 +3 2414 4694 2440 +3 4748 5872 2713 +3 937 4695 5641 +3 6103 7460 6668 +3 4696 2897 1935 +3 2897 4696 4698 +3 5061 6797 5979 +3 630 1166 6331 +3 630 4695 1166 +3 2453 2001 2297 +3 1287 4699 7392 +3 5538 445 6224 +3 3028 4815 6507 +3 1471 4815 778 +3 4700 487 604 +3 4408 4706 361 +3 361 4706 4707 +3 3973 4707 5430 +3 5430 4707 4700 +3 5052 5527 335 +3 4710 4033 5460 +3 4712 6012 6432 +3 3918 4713 221 +3 3148 7386 4060 +3 6844 1703 4383 +3 634 3456 6289 +3 121 4714 7137 +3 3652 3653 3463 +3 3024 334 2157 +3 3425 4715 996 +3 3430 3431 2476 +3 1146 4716 1126 +3 758 4639 1336 +3 4511 4719 6267 +3 6267 4719 7226 +3 6200 460 1951 +3 1951 7313 6200 +3 6566 4721 483 +3 4721 1951 2417 +3 5537 5290 4035 +3 6225 4722 5290 +3 5079 3024 2157 +3 47 1493 2110 +3 3773 4724 2907 +3 369 3705 4001 +3 641 4725 4418 +3 1321 4251 2953 +3 1402 4725 4595 +3 1440 3660 2761 +3 5918 4727 5138 +3 2978 4727 5906 +3 7159 334 3441 +3 3633 3770 3657 +3 645 2593 4893 +3 645 4869 2593 +3 3575 725 3090 +3 5279 4533 6404 +3 2546 4982 3834 +3 2382 4732 781 +3 697 409 4646 +3 959 761 6767 +3 781 5704 2382 +3 301 7117 6986 +3 3659 1450 2842 +3 3205 1031 649 +3 3205 4734 784 +3 3517 1576 3634 +3 493 665 1228 +3 2546 4735 2041 +3 5264 4736 5652 +3 1816 2541 4715 +3 1852 7159 3441 +3 5652 4736 2043 +3 1450 3659 5837 +3 1938 2749 4050 +3 1760 2988 650 +3 1880 5180 5924 +3 2409 1761 3010 +3 7370 7372 6282 +3 6476 4737 1193 +3 1193 4737 655 +3 700 2287 3669 +3 4982 2546 2041 +3 13 1952 654 +3 3499 1320 2315 +3 654 4741 6182 +3 3673 4741 1067 +3 653 1067 4741 +3 3798 4744 6886 +3 4745 956 4826 +3 956 4745 4776 +3 857 657 2348 +3 1243 4748 2713 +3 5805 5363 3645 +3 5521 114 3217 +3 1515 7001 1793 +3 4754 1258 1241 +3 3496 6167 3644 +3 4754 5628 1070 +3 1060 5211 2212 +3 4756 3761 4510 +3 6677 4760 104 +3 3079 1915 5876 +3 1070 1258 4754 +3 2528 5224 5265 +3 7087 4761 3451 +3 4325 623 6365 +3 14 5064 5069 +3 4764 6117 5571 +3 4410 2574 4038 +3 323 3641 3112 +3 661 1267 4885 +3 1547 4766 6132 +3 6132 4766 5547 +3 4584 5547 4766 +3 6243 4767 5992 +3 5992 4767 5986 +3 4895 3702 972 +3 2816 4516 3395 +3 1590 6914 4127 +3 747 4988 6718 +3 4897 2450 1367 +3 2721 4771 124 +3 668 4593 3100 +3 7052 5900 6027 +3 2973 4773 63 +3 6580 4335 3638 +3 2286 5926 1419 +3 673 4775 3806 +3 1690 4895 972 +3 3630 4204 4945 +3 6076 6778 1856 +3 4775 2990 977 +3 2990 4775 2425 +3 4744 4745 6886 +3 214 594 2758 +3 5064 14 2128 +3 3558 704 956 +3 4879 4779 3684 +3 3684 4779 4776 +3 134 4918 5201 +3 1124 5069 5064 +3 4673 2893 308 +3 4780 6608 4781 +3 4263 4318 2889 +3 2087 5242 7314 +3 680 1562 1386 +3 580 4783 6101 +3 4784 4191 417 +3 4191 4784 332 +3 5368 4785 3567 +3 3567 6491 264 +3 3063 5286 727 +3 3984 4789 2840 +3 3512 3227 5948 +3 7298 7435 2319 +3 3637 6982 4468 +3 4556 4558 4997 +3 5911 6298 3622 +3 4002 5982 379 +3 999 5903 3705 +3 4052 4792 683 +3 6991 2426 1736 +3 2402 3621 2260 +3 955 3225 684 +3 684 4792 4000 +3 3240 2862 686 +3 4257 4198 772 +3 1017 4798 7070 +3 2068 687 5081 +3 626 3213 1134 +3 1029 687 1192 +3 4524 4800 3756 +3 2429 5910 3756 +3 689 520 7374 +3 689 4801 5885 +3 5095 731 3153 +3 6074 4704 690 +3 4803 1766 6241 +3 6064 7113 6118 +3 3619 1534 2544 +3 3172 5895 6632 +3 7370 4679 5070 +3 3616 677 6838 +3 5121 5153 1006 +3 726 2767 4012 +3 726 4829 2767 +3 6503 160 6817 +3 3080 4807 5687 +3 5733 4808 2473 +3 1725 5820 3886 +3 5297 4809 5421 +3 1938 6215 1441 +3 5421 4809 6571 +3 1004 5545 312 +3 5388 7146 5396 +3 6889 4810 6162 +3 1812 6162 4810 +3 5819 3135 5211 +3 2461 3894 208 +3 817 1228 665 +3 6913 5052 3794 +3 692 3162 6156 +3 693 335 3682 +3 2084 2648 580 +3 698 5055 5264 +3 4817 5503 140 +3 1828 3732 904 +3 3732 1961 1971 +3 5385 3395 3843 +3 3723 4624 5955 +3 1961 3732 1828 +3 5028 1359 7325 +3 4060 3560 7387 +3 1278 5136 79 +3 3509 2959 4274 +3 3839 4819 3065 +3 3065 4819 6456 +3 2212 6350 6879 +3 3135 5819 131 +3 4054 3731 4850 +3 4093 7066 4009 +3 2420 1511 3988 +3 453 2667 2150 +3 5385 2283 290 +3 279 3264 1665 +3 453 3504 5999 +3 694 1934 864 +3 1697 7155 3912 +3 1971 4468 2879 +3 4826 956 704 +3 4827 1108 375 +3 1455 5136 7267 +3 1108 4827 912 +3 4162 4828 2714 +3 3021 6757 453 +3 4828 4826 902 +3 162 7320 3983 +3 3968 7018 4410 +3 705 5110 1331 +3 705 4829 5110 +3 4339 5165 7332 +3 2098 4806 6353 +3 2767 4829 2432 +3 5385 5570 3400 +3 4340 4830 4540 +3 4540 6526 4340 +3 3006 664 4601 +3 6860 6321 4048 +3 2438 1500 7516 +3 4832 3670 1804 +3 815 4311 801 +3 2422 7298 2319 +3 7000 4836 3568 +3 7390 4839 4836 +3 4290 3357 4665 +3 5194 5879 1682 +3 1500 2438 3683 +3 6652 1924 7203 +3 1607 2285 4630 +3 883 5960 4337 +3 2993 5924 5180 +3 6035 6671 636 +3 2465 3559 711 +3 711 3751 2465 +3 322 4845 1488 +3 537 1544 4846 +3 4457 4846 4847 +3 5315 4847 3196 +3 3196 4847 4845 +3 4927 4848 2424 +3 2424 4848 1307 +3 958 1361 715 +3 5086 3391 1307 +3 1307 715 2424 +3 3611 2591 6449 +3 1615 5908 6963 +3 886 889 5424 +3 2357 3610 6968 +3 2437 2517 1667 +3 498 4852 4830 +3 4852 1266 5151 +3 6244 5203 6948 +3 264 1266 6092 +3 2676 2872 4630 +3 2296 2276 79 +3 716 970 4428 +3 719 5257 5092 +3 541 1090 5057 +3 720 4662 3064 +3 4694 4858 931 +3 1364 6730 3605 +3 6834 5050 499 +3 3860 3861 4334 +3 4304 4862 1734 +3 1734 4862 4863 +3 2000 4863 4860 +3 5674 4083 78 +3 78 4864 5674 +3 3262 4864 3817 +3 4864 2442 103 +3 3645 4865 1445 +3 1445 4865 5729 +3 7015 3145 4682 +3 7313 7298 1020 +3 4361 4362 5202 +3 5996 2582 4840 +3 5948 5802 3604 +3 1491 748 47 +3 1259 3412 806 +3 247 4799 6125 +3 735 4872 4873 +3 1168 7051 5864 +3 7051 4873 4872 +3 6002 4874 1329 +3 1329 4874 1270 +3 2653 2898 5374 +3 702 3002 6744 +3 955 4000 2976 +3 1172 591 4030 +3 3774 6404 7409 +3 4789 4876 2840 +3 2840 4876 6205 +3 4471 4877 2218 +3 3311 4878 3684 +3 3684 4878 4879 +3 4102 4879 2349 +3 1255 782 2917 +3 2349 4879 4877 +3 564 2899 1415 +3 2899 564 729 +3 545 3603 5393 +3 2567 4510 732 +3 732 730 2567 +3 6664 6463 4016 +3 386 1445 4074 +3 737 1381 6142 +3 737 738 4889 +3 4799 6128 6126 +3 4911 4889 1336 +3 2952 4147 7484 +3 738 4890 758 +3 6755 4890 4542 +3 2892 3602 7244 +3 4542 4890 2448 +3 55 5168 7346 +3 723 2552 6180 +3 4385 2382 5704 +3 2417 483 4721 +3 1915 2278 2451 +3 5171 3122 3150 +3 4771 4897 1367 +3 2337 6965 4336 +3 747 2450 4988 +3 5991 3152 1797 +3 7279 4154 7136 +3 5016 3314 6692 +3 4235 4900 3739 +3 4018 3492 5034 +3 3488 4901 4902 +3 3485 4902 2896 +3 905 4929 3598 +3 2896 4902 4900 +3 5102 4144 4265 +3 1688 4904 4905 +3 4905 1513 1688 +3 2235 4905 4903 +3 4903 5760 2235 +3 7347 5168 5491 +3 3825 6664 1633 +3 5611 4907 2 +3 2 4907 2080 +3 1236 6266 1653 +3 3825 3666 550 +3 5602 2418 7378 +3 2258 5219 484 +3 4909 3237 1434 +3 1633 3666 3825 +3 2249 5876 4048 +3 3237 4909 7048 +3 2051 5987 5671 +3 4910 1676 1674 +3 2080 3737 2918 +3 5521 2075 6437 +3 3585 5052 6913 +3 6557 746 2452 +3 4155 4460 5125 +3 2784 763 745 +3 745 4913 5323 +3 2078 4907 3447 +3 1915 2645 2278 +3 1581 4913 746 +3 4179 6222 3038 +3 6587 943 1921 +3 1881 5508 1167 +3 5847 4914 5036 +3 4986 4916 5039 +3 923 5248 2151 +3 3626 4634 6424 +3 2659 1607 3794 +3 4335 5606 4765 +3 5273 4919 5904 +3 289 863 6884 +3 1887 4374 444 +3 2337 6990 5165 +3 3596 7476 5012 +3 2803 4922 3836 +3 6463 6664 6549 +3 3836 4922 5108 +3 1140 5231 6254 +3 5855 755 5541 +3 753 3186 4393 +3 753 4925 3186 +3 2111 4925 6459 +3 176 5970 2275 +3 6459 4925 4923 +3 256 6899 6355 +3 4848 3851 342 +3 3666 3068 550 +3 4191 4452 706 +3 2982 4025 225 +3 4191 706 417 +3 3251 6494 3243 +3 6637 3193 4966 +3 2161 2929 6736 +3 2929 4930 757 +3 4930 4964 965 +3 3322 5352 5858 +3 3001 3333 2995 +3 7344 3111 760 +3 760 4934 7344 +3 5931 4934 2453 +3 6517 4753 4820 +3 2453 2297 5931 +3 3097 4936 6732 +3 3702 2091 646 +3 6732 4936 766 +3 490 4377 2376 +3 4774 2452 764 +3 764 4938 3398 +3 2387 282 3981 +3 553 4938 4891 +3 762 4891 4938 +3 768 5734 1185 +3 768 5448 1005 +3 773 4434 5838 +3 773 1007 4434 +3 695 2992 357 +3 3544 4940 3195 +3 1466 7484 4147 +3 5309 6192 6033 +3 1205 994 451 +3 6585 5468 3592 +3 4397 4942 6315 +3 2272 750 4444 +3 6315 4942 4940 +3 1463 4943 3294 +3 5527 5154 3376 +3 5713 5808 5632 +3 2861 1179 5262 +3 4944 4204 1517 +3 2483 4945 5096 +3 6190 4946 5238 +3 5238 4946 986 +3 1985 2367 779 +3 779 5395 1985 +3 7353 6738 6505 +3 2008 4289 780 +3 781 4734 2693 +3 784 4952 5984 +3 5984 4952 6235 +3 5024 4717 3091 +3 6235 4952 6401 +3 2611 1902 5968 +3 4955 938 533 +3 4955 4957 1704 +3 2649 7483 4355 +3 1903 4957 4954 +3 1639 7427 5215 +3 4841 1437 1579 +3 4954 5583 1903 +3 3249 4959 6999 +3 4330 3453 5934 +3 6999 4959 785 +3 788 2583 1534 +3 3938 480 1457 +3 789 1246 7022 +3 5995 4962 479 +3 4351 5955 4624 +3 3961 3272 3289 +3 2629 4963 4965 +3 3367 4965 5977 +3 5977 4965 4962 +3 3446 6432 6012 +3 3781 1949 4144 +3 2271 4749 2666 +3 3777 3773 2907 +3 568 454 4077 +3 2903 7336 6046 +3 5935 4967 6300 +3 3968 3867 7341 +3 5481 4968 4648 +3 790 4213 5544 +3 5138 4969 5224 +3 4175 6842 6084 +3 795 3650 5529 +3 4886 4970 6498 +3 700 3669 980 +3 3237 2051 796 +3 796 5929 3237 +3 2222 4973 6104 +3 4044 4975 7124 +3 7124 4975 5340 +3 3468 4976 3706 +3 3941 4977 5865 +3 5865 4977 4978 +3 727 4978 3063 +3 3063 4978 3396 +3 4410 7018 2574 +3 5752 646 2756 +3 2305 2000 3791 +3 805 2945 2859 +3 358 4981 6417 +3 6417 4431 358 +3 5770 7498 305 +3 4093 3240 761 +3 1162 4148 164 +3 806 891 4315 +3 5533 6173 2062 +3 1421 4983 3118 +3 3118 5462 1421 +3 5847 5036 1259 +3 810 233 3412 +3 639 4326 7301 +3 583 577 3581 +3 4610 4987 6469 +3 6469 4987 5889 +3 5158 1140 6254 +3 811 3341 2379 +3 5377 3580 5378 +3 6160 1483 813 +3 4544 4546 4855 +3 6519 4992 2989 +3 2989 4992 4994 +3 6034 4838 2703 +3 3127 2967 1448 +3 4701 4994 4990 +3 205 4637 278 +3 3590 6608 130 +3 6312 4998 3681 +3 3681 4998 4999 +3 3305 3178 5001 +3 5399 5690 814 +3 1189 987 6191 +3 1948 3781 1689 +3 2479 2617 1227 +3 5135 6426 6088 +3 5006 2922 6121 +3 4755 2019 2324 +3 818 7476 3198 +3 3448 2718 7189 +3 7092 6834 5008 +3 3774 436 7092 +3 87 6090 1954 +3 3740 1470 214 +3 820 3025 3642 +3 5011 2813 729 +3 2813 5011 6539 +3 2534 6817 2485 +3 5149 366 2447 +3 7476 818 5007 +3 5012 2742 3596 +3 920 7002 5160 +3 3890 5014 6672 +3 5144 5018 500 +3 500 5018 7258 +3 1 5274 2902 +3 409 6268 4680 +3 3646 5617 6857 +3 4435 3998 3253 +3 1401 4139 566 +3 4354 1277 1884 +3 6205 5019 1009 +3 4683 3253 4406 +3 4215 5020 4548 +3 4548 5020 5026 +3 4301 5026 3232 +3 3232 5026 5019 +3 7325 5233 5028 +3 5617 3646 6872 +3 3801 6306 588 +3 249 1094 5030 +3 279 659 3264 +3 3620 6836 6503 +3 2499 3575 3090 +3 659 5035 3264 +3 1195 4553 1337 +3 815 4313 3742 +3 4553 5035 1082 +3 4916 810 1259 +3 4916 823 5039 +3 289 6884 6914 +3 1052 2250 5574 +3 6700 568 4077 +3 4766 5039 823 +3 2074 5671 5987 +3 5331 6346 4411 +3 5860 5043 6661 +3 5043 6214 2871 +3 2905 2782 1225 +3 4789 5045 2622 +3 2072 6605 2717 +3 1527 4991 4924 +3 2622 5045 826 +3 2836 1467 4147 +3 6164 2674 1643 +3 5318 5344 1930 +3 826 499 5050 +3 149 3519 827 +3 149 827 5051 +3 3243 5053 3884 +3 7026 7027 4011 +3 3742 6336 4733 +3 5797 5053 1442 +3 5536 6533 5054 +3 3333 3508 3986 +3 830 3206 480 +3 3024 5079 5692 +3 5062 3359 5660 +3 2035 5063 7232 +3 1981 3939 7407 +3 1763 5063 2489 +3 2489 4536 1763 +3 4454 4785 5368 +3 2613 5065 2764 +3 2605 4383 1703 +3 5071 2261 255 +3 2261 5071 7174 +3 1696 3554 2380 +3 4211 5072 1904 +3 1904 5072 6573 +3 3755 4340 2003 +3 6021 6522 3565 +3 5072 4731 6251 +3 834 5074 7489 +3 3283 5075 3083 +3 3435 5076 5397 +3 5397 5076 6288 +3 3562 4884 850 +3 6049 1500 694 +3 4784 5077 835 +3 5692 5079 6408 +3 835 4926 4784 +3 3632 5048 6284 +3 5080 833 992 +3 5341 5080 5074 +3 2715 3561 422 +3 5074 5077 7489 +3 5701 4224 3807 +3 3755 2003 809 +3 4876 5083 3232 +3 3232 5083 6686 +3 2385 5084 2622 +3 2665 5109 6625 +3 2432 2560 2767 +3 2388 4579 7437 +3 6757 6816 6773 +3 3265 1864 3122 +3 3495 3173 4859 +3 5619 6165 4447 +3 6281 5090 3167 +3 2290 2853 6844 +3 3167 5090 2594 +3 1332 6192 2816 +3 2853 1802 2496 +3 2518 2347 7171 +3 5401 5327 5318 +3 6669 6666 633 +3 3687 7459 7456 +3 839 3200 3299 +3 639 4545 4485 +3 4204 4944 5096 +3 3441 4087 1852 +3 5455 3055 2571 +3 7363 2483 842 +3 1113 6461 2663 +3 6883 3725 845 +3 2118 4580 4396 +3 6667 4539 4782 +3 4650 6848 3553 +3 2829 7494 800 +3 845 1849 6883 +3 5099 4711 5716 +3 3593 7110 4239 +3 3847 6000 5155 +3 2866 5327 5401 +3 774 848 3797 +3 3971 6458 6858 +3 4073 5104 1483 +3 1483 5104 2498 +3 2351 828 6677 +3 573 1055 1042 +3 2054 3341 811 +3 3709 6517 1526 +3 5207 4122 597 +3 2829 3624 7494 +3 2828 3801 588 +3 4756 4760 3761 +3 4148 2150 164 +3 2156 6405 5108 +3 1142 3723 2155 +3 423 5108 4922 +3 1751 2003 4340 +3 2012 2665 1159 +3 4348 542 5244 +3 6624 5109 4459 +3 1532 4459 5109 +3 6690 5198 1653 +3 850 3574 3562 +3 4458 5112 2096 +3 5114 209 2096 +3 2499 3090 853 +3 5542 1366 1312 +3 5117 3075 6544 +3 3069 5118 2610 +3 2610 5118 5182 +3 6060 5119 2348 +3 256 5537 6899 +3 2348 5119 857 +3 49 2190 3472 +3 1960 2755 6341 +3 2947 4626 5721 +3 273 5311 6476 +3 857 2755 5123 +3 2672 859 32 +3 5126 6459 4923 +3 2109 858 1324 +3 4144 4145 4398 +3 465 5412 115 +3 2079 3547 2971 +3 7459 3687 740 +3 861 3022 831 +3 2768 6520 7286 +3 2887 3202 5781 +3 5414 3073 865 +3 865 1068 5414 +3 4618 5133 2500 +3 130 5137 3590 +3 3395 4516 3843 +3 1872 5139 5689 +3 5689 5139 1958 +3 3498 3495 4859 +3 2704 3078 202 +3 7262 4363 5582 +3 5142 5578 5469 +3 4447 1056 3929 +3 7143 5547 7431 +3 2583 3620 6503 +3 7422 5144 118 +3 118 5144 7408 +3 2806 3544 3195 +3 7259 5150 500 +3 5982 4002 2013 +3 5151 4557 4852 +3 4557 5151 873 +3 4092 4559 5155 +3 6794 5434 7281 +3 873 3847 5155 +3 3532 5156 318 +3 548 5157 6088 +3 4991 6276 6861 +3 903 5162 4831 +3 4831 5162 6828 +3 3393 5477 718 +3 2728 5164 5167 +3 6837 5167 6070 +3 6070 5167 5163 +3 7058 2759 7431 +3 6681 2067 165 +3 3523 5169 880 +3 880 5169 1122 +3 2690 6354 6375 +3 875 4652 1807 +3 2465 3751 5976 +3 4652 5746 1398 +3 3538 3539 2162 +3 5513 6681 2434 +3 4738 1198 878 +3 4585 4586 2325 +3 6530 5174 6998 +3 6998 5174 5175 +3 7493 5175 2964 +3 2964 5175 5173 +3 3172 6632 7332 +3 5507 4649 1160 +3 6830 7112 6887 +3 916 5176 921 +3 6096 2252 5409 +3 7186 4253 5572 +3 133 5177 5179 +3 1106 2464 184 +3 1106 5742 2464 +3 5181 2610 5182 +3 5117 5118 3075 +3 1533 1929 468 +3 1264 2238 1580 +3 786 4344 1300 +3 5426 3659 2842 +3 786 5183 6140 +3 3173 5184 4859 +3 6688 6873 1201 +3 3572 4974 6943 +3 6688 5185 5337 +3 4845 5186 3196 +3 3196 5186 1593 +3 3384 6538 1686 +3 3592 5187 5541 +3 1938 1441 6988 +3 2787 4432 2512 +3 797 5145 5479 +3 5484 5154 5010 +3 530 2868 3391 +3 3459 3331 2016 +3 2667 453 6757 +3 1125 5190 1420 +3 5190 5565 1046 +3 749 2567 6836 +3 1132 1466 4841 +3 7301 7450 5087 +3 5390 5192 4299 +3 558 676 4222 +3 5649 1342 4814 +3 6587 1921 2352 +3 2208 5193 311 +3 5692 2919 1557 +3 311 5193 1298 +3 2863 7066 4093 +3 883 4842 5960 +3 5879 5194 1299 +3 2673 4853 3640 +3 2011 1717 5631 +3 5967 6297 5145 +3 4353 2501 2274 +3 3194 5197 5200 +3 6548 5200 450 +3 450 5200 4081 +3 5152 1485 3322 +3 2652 3322 1485 +3 5202 7173 4361 +3 5182 2270 5181 +3 5475 3717 2519 +3 6644 7400 3883 +3 275 4949 2377 +3 5015 4155 3793 +3 5015 5130 7377 +3 2760 5204 5436 +3 3771 5562 1111 +3 6224 5205 5503 +3 5836 5208 5272 +3 5272 5208 5603 +3 3683 2876 945 +3 1157 5209 5926 +3 5209 6436 1419 +3 5210 6656 891 +3 2369 7468 3962 +3 5015 4920 6257 +3 638 4286 90 +3 90 5594 638 +3 19 61 1889 +3 4448 6883 1849 +3 1356 5217 6918 +3 3932 5218 2302 +3 812 275 5552 +3 2302 5218 894 +3 6302 2066 5562 +3 4560 5784 6552 +3 2053 870 2059 +3 2869 2059 870 +3 5775 5223 2463 +3 894 2463 5223 +3 4968 4969 2355 +3 5265 5224 5025 +3 2260 679 2402 +3 5225 5763 6701 +3 5763 5225 7171 +3 5913 5226 4581 +3 6440 5227 2381 +3 5979 2027 5343 +3 354 6726 3530 +3 5647 181 2052 +3 2381 5227 5228 +3 3259 5228 5492 +3 2565 2889 3363 +3 2608 3529 817 +3 5098 4396 4580 +3 5492 5228 5226 +3 6556 1113 2646 +3 1398 3857 3527 +3 621 4738 878 +3 1529 3526 534 +3 2027 5979 1095 +3 5020 5230 1009 +3 1009 5230 7035 +3 77 5231 5892 +3 4460 4441 5125 +3 5892 5231 1140 +3 897 3189 2792 +3 4314 5232 7325 +3 5233 7325 897 +3 7043 2487 2412 +3 3613 4894 5570 +3 2412 2505 6758 +3 5573 5208 2259 +3 4867 1995 5234 +3 5048 5393 1575 +3 3523 880 3757 +3 4817 5234 5511 +3 5511 5234 6811 +3 899 257 73 +3 5624 6036 3521 +3 669 6736 2929 +3 5235 5236 7042 +3 469 2739 2734 +3 5214 5236 5235 +3 2578 2697 6897 +3 7379 7377 6264 +3 696 5553 2800 +3 4101 4102 2349 +3 6458 3601 2688 +3 368 5240 5241 +3 368 5241 906 +3 2215 3589 7056 +3 3589 5241 5239 +3 2590 6454 6361 +3 1124 5242 5069 +3 6438 908 787 +3 5784 2898 6552 +3 707 1716 907 +3 907 5245 3481 +3 6916 5245 2936 +3 2584 4995 6618 +3 7228 6359 3516 +3 2936 5245 2507 +3 2141 5424 7385 +3 2968 3870 6461 +3 6087 5038 7179 +3 1742 7382 2059 +3 145 5666 2058 +3 7443 5666 145 +3 4302 2508 3904 +3 5649 6427 1342 +3 513 2421 2885 +3 1477 3535 5613 +3 7142 7144 3956 +3 917 6799 6796 +3 3094 3789 919 +3 2862 5353 2509 +3 5274 1 2074 +3 5641 2088 937 +3 250 7459 3595 +3 3006 5252 2587 +3 163 7002 920 +3 920 1724 163 +3 5343 135 5016 +3 5524 6894 3722 +3 1249 922 5254 +3 1873 5255 1226 +3 1226 728 1873 +3 5290 2055 1319 +3 931 2440 4694 +3 5258 5092 935 +3 324 5637 420 +3 324 2513 5637 +3 5259 4633 3730 +3 5814 2363 5858 +3 5948 3604 3512 +3 2725 5260 974 +3 2260 2183 679 +3 2990 5261 977 +3 5262 2257 2861 +3 1164 5263 4512 +3 4512 5263 5446 +3 1534 3619 788 +3 4736 5264 5055 +3 5264 5355 698 +3 3140 444 5073 +3 5266 1166 937 +3 3493 5268 6414 +3 6414 5268 5902 +3 4669 4899 939 +3 4670 4104 5934 +3 5338 2477 939 +3 5098 5526 941 +3 941 2759 5098 +3 2759 3765 7431 +3 2771 2661 2569 +3 6356 5271 5904 +3 4132 3364 6905 +3 3170 5273 6648 +3 5987 4671 2074 +3 5518 5277 1267 +3 1267 5277 4885 +3 3774 5279 6404 +3 3661 6181 3386 +3 6517 4820 1904 +3 6499 452 3192 +3 452 6749 890 +3 6018 6016 6019 +3 6933 5698 2598 +3 6650 5282 574 +3 5282 946 3967 +3 6346 5283 3968 +3 3867 3968 5283 +3 6143 6219 1711 +3 946 4833 5284 +3 3599 5286 6990 +3 6990 5286 7039 +3 5762 4400 1744 +3 7039 5286 5287 +3 3063 5287 5286 +3 380 5474 1450 +3 2186 380 2808 +3 1136 5609 948 +3 948 6590 1507 +3 2055 5290 5537 +3 3800 5291 4786 +3 5902 5292 799 +3 799 5292 5293 +3 4392 5293 3313 +3 6704 4880 3988 +3 3313 5293 5291 +3 4676 4675 195 +3 6475 5296 2057 +3 2057 5296 5493 +3 2952 7484 5950 +3 2204 3720 7163 +3 4809 4233 2473 +3 2739 1427 2734 +3 5599 1208 736 +3 5271 5299 1021 +3 1021 5299 5300 +3 197 5700 4116 +3 5516 5300 5421 +3 5421 5300 5297 +3 5147 5301 7138 +3 748 4634 4914 +3 7323 7326 438 +3 628 5908 4851 +3 6019 6391 6018 +3 985 5301 1712 +3 6768 5302 1813 +3 2417 5303 483 +3 7251 3378 3506 +3 483 5303 5621 +3 539 951 4419 +3 951 979 4419 +3 4182 736 1208 +3 5306 6615 1265 +3 6181 6238 5820 +3 3570 2490 443 +3 5380 6615 953 +3 5889 5307 3160 +3 3160 5307 6838 +3 3805 5308 1176 +3 2150 3551 3504 +3 954 569 3834 +3 3531 5310 6983 +3 5863 6247 1174 +3 6983 5310 961 +3 957 3053 4496 +3 5313 5321 3075 +3 3196 5314 5315 +3 736 7148 2771 +3 2441 6152 2883 +3 2667 4996 164 +3 261 3248 4120 +3 486 5719 5756 +3 3188 5315 6435 +3 6435 5315 6996 +3 2295 2756 3500 +3 3553 2091 6978 +3 7328 5719 486 +3 3557 2146 1064 +3 6482 5727 5719 +3 3172 2828 588 +3 3498 5432 2860 +3 6697 6172 1518 +3 962 4590 2152 +3 962 7355 4590 +3 745 5323 1842 +3 201 5417 3493 +3 1842 2784 745 +3 1826 4449 565 +3 7504 5727 6482 +3 691 2104 6613 +3 3892 5326 965 +3 965 4964 3892 +3 2699 5328 2523 +3 4496 5856 5329 +3 6144 5330 5346 +3 5346 5330 6862 +3 3967 5331 574 +3 1726 5331 4411 +3 5181 2270 1345 +3 2977 5332 22 +3 5332 1223 2526 +3 966 4575 3416 +3 967 6001 1329 +3 1624 7269 6761 +3 5339 3490 234 +3 7390 4836 1912 +3 7456 5334 3687 +3 3687 5334 1780 +3 4751 6494 3399 +3 2570 4576 5863 +3 2657 6479 212 +3 1639 1715 2547 +3 5184 5185 4859 +3 3490 3491 2261 +3 4402 4908 3382 +3 1852 4087 2746 +3 5683 5339 5340 +3 4973 4975 6104 +3 5884 5146 6676 +3 7124 5340 5337 +3 7397 5342 2372 +3 2372 5342 3950 +3 5597 6115 2444 +3 968 4477 2961 +3 7151 1323 5317 +3 3915 3917 2341 +3 4138 5348 7291 +3 7291 5348 5345 +3 3260 3259 5492 +3 5350 4338 2407 +3 4338 5350 6486 +3 4243 5351 5004 +3 5004 5351 971 +3 473 2113 971 +3 5707 338 5336 +3 970 3484 4428 +3 3201 5354 5351 +3 5355 5266 698 +3 5266 1392 1166 +3 3440 5357 4552 +3 5707 5336 1638 +3 4552 5357 6316 +3 5358 7214 549 +3 5359 2641 932 +3 2641 5359 975 +3 5958 5360 3569 +3 3569 5360 2529 +3 974 5261 269 +3 5708 6129 3485 +3 977 5359 4775 +3 4865 5363 2593 +3 3997 5365 5366 +3 5805 5366 5363 +3 6157 5369 4011 +3 1758 4133 3482 +3 6944 5370 373 +3 373 5370 6022 +3 5984 3205 784 +3 2868 84 4849 +3 7009 707 907 +3 7148 4182 6758 +3 6558 1272 2056 +3 3612 5373 929 +3 5160 7002 6743 +3 1099 5374 3082 +3 2388 2399 7088 +3 7019 5374 3445 +3 7460 1901 6668 +3 3580 3579 7041 +3 6156 5382 3477 +3 1901 7461 1170 +3 5377 5378 5379 +3 6818 6743 3012 +3 2514 4082 5994 +3 978 5379 6823 +3 6823 5010 978 +3 979 5306 4419 +3 980 1868 700 +3 7319 4272 1312 +3 4064 5382 3355 +3 1180 7481 7479 +3 2309 6603 869 +3 1107 6535 3476 +3 1860 5387 6388 +3 5387 5384 837 +3 4238 5386 1796 +3 5192 3166 7204 +3 6086 4020 3139 +3 4617 5390 2535 +3 4825 5756 2511 +3 6181 3661 6238 +3 5765 5787 2047 +3 984 4299 4660 +3 6333 5358 2253 +3 6846 4630 2285 +3 3342 5391 6644 +3 6644 5391 1975 +3 6799 1974 1365 +3 1019 6019 4326 +3 986 2462 5238 +3 4967 5398 6300 +3 4841 1466 1285 +3 5398 5399 2475 +3 1831 914 4281 +3 5073 444 5906 +3 987 5001 3178 +3 6389 4083 1799 +3 2153 378 158 +3 5399 5395 776 +3 3707 2581 989 +3 989 1558 3707 +3 2071 56 5327 +3 2253 2021 3475 +3 3614 5402 5545 +3 5545 5402 6682 +3 5721 6268 7010 +3 1444 4453 2248 +3 4499 4500 7239 +3 1736 5404 7264 +3 3957 2954 4701 +3 4596 5406 2103 +3 3278 5407 5708 +3 5708 5407 6137 +3 896 4035 3218 +3 6394 3162 3682 +3 3368 5410 384 +3 384 372 3368 +3 3798 3799 671 +3 5413 4926 835 +3 5722 3468 861 +3 4926 5413 5539 +3 3960 5415 6721 +3 6638 5416 201 +3 201 5416 5417 +3 5268 5417 4786 +3 4786 5417 5415 +3 3850 6344 4580 +3 4580 6344 5526 +3 6813 5752 1828 +3 2459 1007 245 +3 4682 5420 4795 +3 7171 5422 2539 +3 7171 2539 2518 +3 2911 5423 7229 +3 3647 5423 7200 +3 4921 2210 5027 +3 911 5765 2071 +3 4658 4659 3447 +3 5974 3466 2433 +3 2150 4148 3551 +3 1533 6850 856 +3 5314 3125 4501 +3 911 5785 5765 +3 4524 3756 3461 +3 5808 5713 1775 +3 162 3983 3607 +3 2724 6858 2688 +3 1528 4703 1184 +3 4619 5428 5467 +3 5371 2492 5044 +3 6567 5429 792 +3 995 4251 6602 +3 4251 995 635 +3 4140 5999 2895 +3 2358 4621 3457 +3 4716 3430 3425 +3 221 4714 2243 +3 5706 5785 911 +3 6289 3456 3454 +3 6096 5409 2845 +3 2795 2484 2069 +3 4422 5124 525 +3 5759 5772 998 +3 5198 5435 6262 +3 1000 5949 1362 +3 5204 5437 5436 +3 7186 5436 5437 +3 5437 5204 1592 +3 4499 5438 660 +3 2967 5439 1448 +3 3449 3142 6044 +3 1448 5439 5581 +3 6499 4837 5078 +3 1003 1795 6695 +3 777 5444 3919 +3 5657 4582 1077 +3 3919 5444 5445 +3 3828 5445 2472 +3 2718 3409 6345 +3 2472 5445 5441 +3 2257 5262 5446 +3 4545 639 3334 +3 4512 5446 1008 +3 1006 6843 1279 +3 6843 1006 5447 +3 4584 3626 7058 +3 2044 168 5085 +3 1005 5734 768 +3 950 5451 4135 +3 5449 5376 4765 +3 3969 3970 536 +3 7322 5919 5452 +3 5453 5536 5054 +3 5453 5452 3969 +3 290 5570 5385 +3 4126 3989 5878 +3 1010 2217 4189 +3 4743 5456 5457 +3 318 4330 3532 +3 4309 4310 2780 +3 2471 5457 2469 +3 7224 2616 4651 +3 3732 1970 904 +3 1884 5159 4354 +3 7021 5458 622 +3 6740 218 3332 +3 4894 2492 5570 +3 218 6740 3649 +3 148 4617 309 +3 4033 5459 3067 +3 4422 4403 6042 +3 3764 4928 4422 +3 717 5460 1559 +3 2172 6146 3890 +3 615 2623 672 +3 2895 3503 1089 +3 4141 2540 6771 +3 1035 5465 2543 +3 1745 2697 2578 +3 5187 5468 2873 +3 2873 5468 6950 +3 4883 2089 4648 +3 1904 4820 4211 +3 4648 2089 1015 +3 2368 930 5950 +3 2615 5481 1015 +3 4690 5470 1015 +3 2193 5473 2252 +3 1450 2788 2842 +3 5919 5475 2519 +3 7032 4346 1423 +3 2567 5476 6836 +3 6836 5476 160 +3 6704 4656 3114 +3 4520 2737 4279 +3 3211 3376 1301 +3 6619 5638 3438 +3 4009 2862 3240 +3 2240 884 6078 +3 5498 4646 409 +3 5163 999 6070 +3 1018 2522 1612 +3 1018 5717 2522 +3 5236 5478 7042 +3 3752 6014 3435 +3 5479 6197 797 +3 3870 1727 1730 +3 5022 5025 5481 +3 1222 5482 6363 +3 3846 223 5482 +3 3473 5482 1019 +3 4583 5484 5010 +3 5725 4560 5305 +3 1020 6200 7313 +3 5922 4853 4498 +3 6914 6884 4127 +3 6145 5346 5487 +3 2043 5859 5652 +3 610 5488 1022 +3 4885 5489 3933 +3 2545 3910 613 +3 2547 1715 1023 +3 6297 983 6607 +3 1023 5488 2547 +3 4854 2238 1264 +3 3425 996 4716 +3 5493 6581 3013 +3 5130 3793 3429 +3 5295 5296 7376 +3 5857 3911 4292 +3 3392 5495 4146 +3 1133 5496 5497 +3 1133 5497 6082 +3 5306 6082 5497 +3 4419 5497 1435 +3 2041 4736 4982 +3 5531 2547 5488 +3 6589 5501 2634 +3 3510 5646 5699 +3 5249 6903 3245 +3 2634 5501 6854 +3 3783 4928 3764 +3 1900 5502 5968 +3 5646 7037 6716 +3 218 5459 3428 +3 4153 5506 981 +3 5146 5884 3814 +3 6809 7458 48 +3 3816 5510 6076 +3 3686 6540 7119 +3 2606 5353 3325 +3 6076 5510 6780 +3 1027 2620 2585 +3 4278 5512 5514 +3 5514 3385 4278 +3 4163 4076 7514 +3 1214 5514 714 +3 2530 2141 1576 +3 6320 134 5201 +3 714 5514 2548 +3 4768 6172 3234 +3 5505 2599 1661 +3 2916 6949 4163 +3 5219 2636 627 +3 5300 3881 1021 +3 6138 3949 3423 +3 3413 5517 354 +3 354 5517 6495 +3 2647 137 5688 +3 5737 5519 5989 +3 2862 4009 7256 +3 5989 5519 1030 +3 1339 930 2887 +3 6021 3565 3418 +3 4103 2476 2698 +3 3467 5520 2550 +3 1213 5519 4429 +3 866 3434 6049 +3 2537 7270 172 +3 4761 5523 3451 +3 5149 2705 366 +3 3451 5523 6220 +3 2237 714 3413 +3 547 6064 2065 +3 6890 991 4267 +3 5159 4232 769 +3 1032 2312 2472 +3 3942 5530 2333 +3 2333 5530 291 +3 3820 5534 802 +3 5819 696 3176 +3 802 5534 6966 +3 2055 5537 5538 +3 6297 5967 983 +3 6493 5539 3847 +3 2388 2244 4579 +3 7088 2244 2388 +3 5371 3400 2492 +3 3847 5539 6000 +3 4419 1435 539 +3 2516 3897 171 +3 3050 5859 2042 +3 5425 2004 3831 +3 1758 5543 6366 +3 1896 3979 1036 +3 2362 806 4315 +3 5544 2913 93 +3 93 5548 5544 +3 2330 2239 481 +3 5623 5548 2556 +3 1038 2987 4668 +3 2987 5425 4668 +3 4172 5550 5216 +3 4472 4054 4850 +3 871 5551 5554 +3 2312 5554 2472 +3 2472 5554 5550 +3 2948 88 3640 +3 6714 5556 3117 +3 3117 5556 6061 +3 7275 7279 7130 +3 5588 2679 1041 +3 5171 3150 4029 +3 1555 5560 1043 +3 1276 3133 1555 +3 2223 6100 4261 +3 1095 5362 5696 +3 257 2027 5696 +3 2975 4022 229 +3 2234 3171 1347 +3 5189 5190 4036 +3 4958 7449 7451 +3 4566 541 5881 +3 1029 5431 2007 +3 1048 1049 372 +3 5996 4840 6409 +3 4337 5567 822 +3 5569 822 1049 +3 2709 6016 6018 +3 2530 2525 886 +3 2868 530 6511 +3 2562 6511 530 +3 5572 4470 3009 +3 5455 5613 2680 +3 1050 2250 5747 +3 5655 5575 3701 +3 3692 5577 739 +3 739 5577 6779 +3 5141 5142 2101 +3 2311 5480 674 +3 5859 3050 1796 +3 6211 4027 5558 +3 7193 5579 4750 +3 3975 5580 2802 +3 2802 5580 5581 +3 5352 3322 545 +3 7086 3573 812 +3 5438 5439 660 +3 1448 5581 5579 +3 5141 5582 3854 +3 3854 5582 7365 +3 7275 7130 7324 +3 3407 3408 516 +3 7112 7115 6587 +3 3576 3513 2568 +3 3522 225 2488 +3 5267 5557 1041 +3 5650 2211 5595 +3 3913 4651 2831 +3 4049 725 3404 +3 2825 6273 3211 +3 3991 6834 2741 +3 6152 6165 2883 +3 2500 2274 4618 +3 638 5594 1542 +3 5650 5595 1057 +3 1059 3924 450 +3 2521 3965 5596 +3 4673 5598 5059 +3 1057 5059 5598 +3 7115 5600 943 +3 943 5600 6588 +3 1843 1063 3779 +3 2018 5601 5573 +3 2039 1143 2132 +3 5272 5603 2572 +3 5205 2572 140 +3 3882 3169 1401 +3 1364 5605 6730 +3 5157 548 4519 +3 1637 5606 4335 +3 4765 5606 5336 +3 2592 5607 3129 +3 4481 5608 5832 +3 1136 5608 1065 +3 1066 3896 5777 +3 1808 7054 2040 +3 7008 2038 5356 +3 1066 7125 3896 +3 4658 5611 5949 +3 5949 5611 1362 +3 7254 5612 226 +3 3403 3193 6421 +3 352 6992 3402 +3 4212 5966 7008 +3 226 5612 6987 +3 3397 2723 1480 +3 633 7480 7481 +3 6698 5975 5614 +3 7457 4082 1574 +3 1068 5594 5414 +3 2650 6994 3366 +3 3872 5616 4137 +3 5616 5618 1997 +3 3394 422 3318 +3 5618 4260 2163 +3 4260 5618 3108 +3 1713 2564 1486 +3 4192 5642 5639 +3 4360 5054 1033 +3 5243 5201 4918 +3 681 5620 1479 +3 195 4675 1313 +3 5302 5303 1813 +3 483 5621 6564 +3 5047 3785 526 +3 415 6011 6053 +3 507 5626 337 +3 3689 5626 4527 +3 3831 3833 4524 +3 4527 5626 1508 +3 6697 5821 296 +3 2164 3393 4984 +3 4146 5378 3392 +3 4495 4216 6326 +3 4216 4495 4211 +3 5695 7215 3181 +3 5629 5627 3427 +3 7227 5628 4754 +3 2485 5628 2534 +3 2233 5653 1787 +3 1959 3391 5086 +3 792 2532 1330 +3 5627 5629 4755 +3 4755 5629 6118 +3 1766 6118 5629 +3 3515 3832 1430 +3 3134 4037 4494 +3 4523 4526 5584 +3 3009 4470 2002 +3 1071 4618 2274 +3 1514 2864 1071 +3 4511 5871 4670 +3 4409 5635 7358 +3 7443 6011 415 +3 3897 350 3387 +3 7358 5635 5634 +3 6818 4697 6649 +3 4415 4416 5492 +3 2985 5636 6852 +3 3438 3440 4552 +3 4758 5639 1073 +3 2688 3559 2465 +3 4190 2198 1199 +3 185 6387 3073 +3 4695 5640 5641 +3 6184 5319 2088 +3 6184 1064 5319 +3 1880 652 615 +3 2002 1489 3009 +3 2681 2029 4532 +3 319 6274 1976 +3 4488 1788 4489 +3 4488 1076 5730 +3 373 6022 6011 +3 5877 2940 1075 +3 4600 5645 4777 +3 1076 5643 5730 +3 5369 5370 4011 +3 614 6716 3931 +3 1572 5649 4814 +3 3947 5654 4568 +3 4568 5654 5656 +3 6031 5656 7057 +3 7057 5656 5654 +3 2877 1080 68 +3 7218 6053 258 +3 4723 3525 133 +3 7103 3733 2136 +3 1943 5927 1011 +3 7233 5660 3359 +3 5660 1494 5062 +3 2900 5661 7367 +3 2737 4520 1078 +3 6682 5664 4068 +3 5711 5665 3518 +3 7508 2573 1891 +3 3518 5665 5667 +3 6966 5667 1498 +3 1498 5667 5664 +3 6056 6109 2158 +3 5699 5669 3510 +3 2002 3211 1301 +3 5670 1937 1886 +3 6484 6485 7201 +3 3450 5388 2703 +3 6426 886 2525 +3 5835 2547 5531 +3 2597 1427 3902 +3 1543 1674 7049 +3 1085 6008 1759 +3 2331 4023 7508 +3 6050 3690 4324 +3 5168 5673 5491 +3 5491 5673 7278 +3 2543 1717 885 +3 1141 3369 3167 +3 5676 72 5717 +3 6749 5677 890 +3 6712 5677 1294 +3 1062 3966 5650 +3 915 6296 2191 +3 5392 3033 4594 +3 3252 5682 2364 +3 7039 2828 3172 +3 2364 5682 5685 +3 372 5567 3368 +3 1876 2293 7004 +3 2821 7010 697 +3 2945 5685 2859 +3 2859 5685 5681 +3 2005 3963 1096 +3 1096 1237 2005 +3 2240 5691 884 +3 6037 884 1098 +3 1519 4209 6717 +3 3445 1099 429 +3 1095 5696 2027 +3 2308 378 2646 +3 6685 812 3573 +3 257 5696 7345 +3 6717 5162 7248 +3 6612 4210 5697 +3 2986 5699 3914 +3 6716 5699 5646 +3 2528 5275 5320 +3 5977 5833 3367 +3 4175 7001 2115 +3 5571 7225 4764 +3 5702 2582 4362 +3 50 5834 7091 +3 4765 5376 1101 +3 385 6105 6056 +3 5089 667 3517 +3 6622 6105 385 +3 1810 603 629 +3 5542 3474 3647 +3 2137 2316 495 +3 6641 2137 495 +3 6503 1534 2583 +3 5412 789 7022 +3 5665 3411 4068 +3 6109 4657 398 +3 1131 5712 5585 +3 2274 5714 4353 +3 4711 5714 5716 +3 4447 7129 1056 +3 2445 3365 5535 +3 833 5662 4333 +3 3372 1083 1496 +3 6017 6258 5823 +3 3524 5716 5713 +3 6636 603 4220 +3 2230 3031 1476 +3 3540 6336 3651 +3 4306 1018 6874 +3 1109 5862 2097 +3 5862 5718 6327 +3 5509 6487 2495 +3 254 7383 3361 +3 6781 6736 5952 +3 6421 3193 4117 +3 3751 6400 2314 +3 2801 1469 2536 +3 5177 5720 5829 +3 3063 4976 494 +3 3801 5723 5725 +3 4560 5725 831 +3 831 5725 5722 +3 489 3018 2623 +3 3404 5728 4049 +3 4049 5728 5729 +3 4869 4865 2593 +3 1445 5729 5726 +3 6086 3139 5835 +3 5924 2993 393 +3 1858 2107 7166 +3 6382 5731 2341 +3 2630 3254 5744 +3 6573 5731 2338 +3 3813 6147 6246 +3 2925 7319 6959 +3 2213 5796 4053 +3 6147 3813 2491 +3 6772 5733 6565 +3 3745 5735 5911 +3 5911 5735 6295 +3 3908 3907 2654 +3 4429 5737 658 +3 3573 7086 2668 +3 2909 4921 872 +3 658 5737 6448 +3 1459 5738 6885 +3 6885 5738 1867 +3 5366 827 3997 +3 5326 3358 957 +3 4614 5739 1116 +3 2263 5418 224 +3 5740 2620 1114 +3 2620 5740 2585 +3 1117 5739 5805 +3 5179 4723 133 +3 2350 10 6158 +3 2195 5745 2370 +3 5745 5746 874 +3 5746 5743 344 +3 3811 5747 2086 +3 2086 5747 5749 +3 3497 3511 3353 +3 6007 5748 2586 +3 2586 409 4680 +3 5750 3409 5188 +3 7258 5751 2937 +3 2937 5751 7474 +3 6255 5753 1643 +3 7143 6235 1718 +3 1643 2674 6255 +3 6978 4895 3014 +3 3014 3013 6581 +3 3858 3720 2204 +3 7095 4569 2776 +3 1104 3256 6096 +3 1104 3096 1463 +3 3350 3351 3301 +3 1816 3803 949 +3 5758 5759 2541 +3 1126 998 1146 +3 5772 5759 5755 +3 1127 3381 4196 +3 3740 2758 6361 +3 1128 6395 7102 +3 1705 6447 7098 +3 6447 1705 1397 +3 6159 6158 1616 +3 4536 1746 5766 +3 338 5707 6460 +3 2282 2399 2388 +3 5161 4111 3347 +3 7234 5768 5961 +3 5769 5961 1129 +3 6304 5769 3161 +3 3161 5769 2588 +3 2589 6241 1766 +3 2224 1131 7314 +3 4228 5047 526 +3 3180 1151 5810 +3 1131 7181 7314 +3 5770 3030 5085 +3 5871 6537 1174 +3 1135 4146 5495 +3 1135 1596 4146 +3 5580 5773 4750 +3 6952 5774 2463 +3 2463 5774 5775 +3 940 2955 6134 +3 2308 6134 158 +3 3610 5775 6968 +3 6968 5775 5773 +3 5776 2949 1501 +3 2949 5776 6122 +3 2388 5563 2282 +3 1573 5777 3896 +3 1718 542 6132 +3 4964 4930 2161 +3 392 5779 6110 +3 6110 5779 5780 +3 4537 5780 6419 +3 6419 5780 5778 +3 3217 114 1139 +3 6777 5783 188 +3 188 5783 6120 +3 3538 2957 4527 +3 4822 5786 1144 +3 1884 5312 3116 +3 6666 7480 633 +3 1145 5786 2162 +3 3338 4445 402 +3 7088 2399 6230 +3 479 3959 3335 +3 3671 5789 5790 +3 3448 5790 147 +3 147 5466 3448 +3 4947 3020 477 +3 1147 5793 1554 +3 2320 1125 1420 +3 6903 5206 3637 +3 2409 5794 1761 +3 6568 5795 6063 +3 6063 5795 6543 +3 1567 1731 6600 +3 1567 5796 5732 +3 7066 2863 1527 +3 7037 5646 6006 +3 1567 2584 6977 +3 6745 5798 3439 +3 6397 5799 3766 +3 3766 5799 6839 +3 4257 4258 241 +3 4173 5802 3608 +3 3608 5802 5806 +3 3710 5806 772 +3 772 5806 5801 +3 513 4051 4072 +3 218 3426 3332 +3 425 484 627 +3 5807 6973 2817 +3 6020 5808 1775 +3 5632 5808 5000 +3 791 6196 2439 +3 6559 1485 4591 +3 4591 3141 6559 +3 5383 4401 2638 +3 5231 77 705 +3 1658 622 1662 +3 6399 2122 1851 +3 5810 1261 3749 +3 1261 5810 1150 +3 2601 7085 1881 +3 2601 2185 7085 +3 5810 511 3180 +3 4010 4009 7066 +3 5099 5816 4711 +3 4151 5816 4321 +3 5311 3549 3555 +3 2910 3327 805 +3 1575 3116 5048 +3 1078 6117 4764 +3 4642 4643 2989 +3 6665 5822 1308 +3 7160 5823 143 +3 3301 6639 3324 +3 143 5823 7081 +3 7250 6246 144 +3 1661 5824 5505 +3 5505 5824 2014 +3 1462 1153 7228 +3 4528 5826 5688 +3 5316 4857 7520 +3 1152 5827 6083 +3 5607 5827 3129 +3 3129 5827 5825 +3 72 6277 6327 +3 6907 5828 4484 +3 6844 4383 2290 +3 6676 6181 5884 +3 3822 5830 5977 +3 5977 5830 5833 +3 3367 3366 5583 +3 2650 5833 5830 +3 2106 6801 1645 +3 31 7449 4958 +3 1275 4953 1585 +3 5706 911 1923 +3 1504 5838 4434 +3 3137 1506 3814 +3 2245 6843 2459 +3 6741 5839 5841 +3 5254 5841 728 +3 728 5841 5838 +3 5655 4038 3323 +3 2284 5842 2665 +3 2665 5842 1159 +3 6935 7434 55 +3 5843 6656 888 +3 6656 5843 4367 +3 1156 4363 1163 +3 1163 5842 1156 +3 2610 5873 3069 +3 5198 6690 2363 +3 919 5846 3668 +3 2257 5263 1495 +3 5428 5850 5467 +3 2539 5848 2518 +3 3036 5852 665 +3 665 5852 2608 +3 2791 2609 6230 +3 7525 4201 7066 +3 5187 5854 5541 +3 5541 5854 6804 +3 5126 5855 32 +3 69 6319 5881 +3 3071 1391 4996 +3 4656 1511 1357 +3 69 2269 7123 +3 5860 2179 1819 +3 2179 5860 6119 +3 1881 1167 2601 +3 5927 756 1011 +3 2343 5864 1537 +3 4050 1119 7521 +3 1750 1583 1205 +3 2252 6096 2193 +3 2782 2842 1225 +3 6140 5867 7051 +3 7051 5867 5864 +3 6156 3162 6273 +3 3871 5868 4565 +3 4565 5868 1529 +3 3641 5870 3112 +3 3112 5870 1531 +3 3720 3858 2310 +3 3069 4496 3053 +3 1277 5312 1884 +3 3629 5875 3615 +3 5242 2224 7314 +3 2643 222 1202 +3 5880 3569 936 +3 3569 5880 1203 +3 156 6861 120 +3 3924 6548 450 +3 2871 5883 6661 +3 6661 5883 5887 +3 6119 5886 2949 +3 2949 5886 1501 +3 276 422 3561 +3 1171 559 1503 +3 612 2607 3079 +3 1239 6924 6040 +3 7163 3720 783 +3 1171 5883 1955 +3 55 6653 7014 +3 1363 5040 557 +3 5307 4987 1176 +3 4462 4464 4855 +3 5483 5890 5891 +3 2050 1543 1759 +3 5798 5891 3160 +3 3160 5891 5889 +3 2958 5896 3215 +3 4545 3334 4939 +3 5735 5897 6565 +3 3640 1777 4881 +3 6565 5897 5898 +3 6131 5898 371 +3 1162 3572 4123 +3 371 5898 5896 +3 3506 6502 1464 +3 2506 6310 6277 +3 3370 5899 3767 +3 4226 2612 6044 +3 513 4072 3696 +3 6921 5900 616 +3 612 3079 2249 +3 616 5900 7241 +3 5941 5901 799 +3 5219 2258 2338 +3 5292 5268 4786 +3 6414 5902 5905 +3 5742 5905 2464 +3 2464 5905 5901 +3 6315 4940 3312 +3 5214 5907 107 +3 5979 2563 5061 +3 3684 4744 3311 +3 6963 5908 6894 +3 3436 5909 6894 +3 5529 3650 3308 +3 2927 5912 4581 +3 4415 5913 3627 +3 2492 3400 5570 +3 3627 5913 5914 +3 1869 7410 1423 +3 5357 5914 7214 +3 7315 6310 2506 +3 7214 5914 5912 +3 1175 4712 4033 +3 7346 6653 55 +3 2618 5916 6444 +3 7053 5012 5917 +3 3867 5920 4898 +3 2617 4898 1227 +3 6306 5305 6365 +3 4231 4760 6677 +3 2008 2256 1595 +3 5921 5734 5262 +3 4124 4562 436 +3 5734 5921 1185 +3 318 134 6320 +3 4703 4482 1184 +3 1184 5925 1528 +3 2405 3306 6580 +3 2735 5925 208 +3 1182 208 5925 +3 6982 5761 2879 +3 4577 1730 6526 +3 2365 5671 1 +3 3237 5929 1434 +3 1186 4386 631 +3 4934 4013 7344 +3 5150 7479 2197 +3 1613 1187 5930 +3 4978 5932 5865 +3 4023 2310 6630 +3 5865 5932 2624 +3 4680 4626 6007 +3 1188 6065 1161 +3 2475 5933 6300 +3 6300 1191 2625 +3 5877 5645 3300 +3 3885 338 6460 +3 2333 1037 136 +3 3706 5935 2625 +3 2429 5939 5910 +3 1426 1010 6039 +3 2745 3298 5844 +3 5910 5939 1248 +3 2519 3717 3295 +3 5901 3520 2464 +3 156 5338 939 +3 568 6700 1506 +3 3320 5944 5945 +3 5293 5945 463 +3 463 799 5293 +3 6928 4210 6612 +3 5946 6228 3200 +3 6228 5946 5947 +3 2204 7163 3746 +3 3464 6068 2780 +3 4463 1681 1197 +3 1197 5951 432 +3 5951 4811 878 +3 5947 4811 5951 +3 5799 5953 3439 +3 3439 5953 6412 +3 5986 5954 4950 +3 2728 6160 5956 +3 1202 5880 3778 +3 6048 6577 314 +3 216 3291 600 +3 5959 6048 1203 +3 5064 5959 1124 +3 3286 3287 126 +3 1124 5959 2627 +3 3662 5338 156 +3 488 1093 5962 +3 5963 4811 5947 +3 1204 5964 5172 +3 5964 1169 621 +3 1169 5964 2628 +3 5287 3063 494 +3 5033 5965 249 +3 5287 2828 7039 +3 2220 3680 3279 +3 249 5965 1274 +3 1211 2143 5560 +3 5717 5718 2522 +3 5821 6697 947 +3 5506 5502 981 +3 732 3277 2044 +3 856 6850 7198 +3 6406 2894 2038 +3 4141 4321 2540 +3 3245 5752 2756 +3 362 3276 4431 +3 6903 3637 4468 +3 2345 2800 5553 +3 2550 5969 7132 +3 7132 3467 2550 +3 1436 4421 2953 +3 1574 6275 3636 +3 6673 6820 3274 +3 3607 2908 162 +3 231 7478 2875 +3 5971 3385 1214 +3 4385 1288 2219 +3 3934 2733 765 +3 3385 5971 5973 +3 1215 6808 2750 +3 176 5973 5970 +3 3466 3465 3261 +3 3677 2668 1360 +3 4530 5974 5981 +3 4530 3424 1668 +3 5980 5981 328 +3 5981 6337 1216 +3 1500 6049 7516 +3 6337 5981 5974 +3 815 5983 2632 +3 3677 1360 793 +3 7143 5984 6235 +3 2386 5633 4566 +3 1079 334 1039 +3 4999 3696 3681 +3 5954 4767 4328 +3 5992 5986 7162 +3 1217 3808 5815 +3 1218 3510 6790 +3 325 6429 876 +3 4057 5990 1446 +3 2769 2903 947 +3 5783 5990 6363 +3 1222 6363 5990 +3 3335 5993 479 +3 3822 5995 3417 +3 3417 5995 6234 +3 3170 4369 4623 +3 3307 950 1143 +3 453 5999 6771 +3 2526 22 5332 +3 4089 6002 3155 +3 6003 470 3293 +3 1224 2374 4156 +3 5767 5744 4194 +3 6003 6001 1223 +3 6138 3423 3204 +3 4361 3268 927 +3 7074 6087 1158 +3 1881 7085 7473 +3 6338 152 2036 +3 1690 5818 3983 +3 2196 4503 3267 +3 1226 5254 728 +3 3209 7477 7472 +3 1228 4810 493 +3 5677 6749 1294 +3 1229 6010 6162 +3 6862 6010 794 +3 3021 3450 6757 +3 7118 7120 6672 +3 1655 3140 5598 +3 3182 6334 4164 +3 794 6010 97 +3 4768 6651 1518 +3 5317 3078 7151 +3 2026 6442 6339 +3 6362 6013 2082 +3 699 6837 6922 +3 3265 6879 3179 +3 2082 6013 6452 +3 5076 6014 3083 +3 4924 1394 217 +3 6020 1775 5128 +3 2010 447 3931 +3 7516 6049 3434 +3 98 2036 45 +3 1100 5000 5808 +3 1429 4403 4444 +3 3993 6884 4688 +3 1231 4286 638 +3 5016 6692 5757 +3 4331 4332 807 +3 1232 6025 6628 +3 6478 4770 4059 +3 5646 7436 6006 +3 2958 6025 5975 +3 5800 5809 4762 +3 5975 6025 5614 +3 350 6026 1280 +3 1362 6028 1000 +3 6028 6029 1000 +3 4908 6029 3382 +3 3382 6029 6026 +3 5820 6238 3886 +3 6475 2057 85 +3 6030 1100 6020 +3 6030 6387 1853 +3 749 6836 3620 +3 4318 292 3571 +3 5656 4055 6632 +3 3285 3522 5710 +3 674 2701 5938 +3 5624 6031 7210 +3 6762 3521 6036 +3 1677 6036 7210 +3 782 1255 1238 +3 1238 6037 2581 +3 1237 5691 478 +3 2603 3254 1946 +3 884 6037 2640 +3 1239 2223 4261 +3 3985 5198 2363 +3 7094 6236 6675 +3 1429 1385 4403 +3 7454 1945 596 +3 7454 6042 1387 +3 2955 940 2671 +3 6044 3142 4226 +3 2633 1277 4354 +3 5248 2984 5869 +3 4113 5655 3701 +3 3817 3693 3262 +3 6087 7074 5038 +3 6046 383 2903 +3 3092 5535 3713 +3 3644 6054 3862 +3 2335 2847 455 +3 6338 2894 876 +3 3254 2630 1924 +3 871 5554 1040 +3 1242 1439 6456 +3 3922 3721 7012 +3 2716 6058 6059 +3 6059 5191 2716 +3 3547 6059 2971 +3 2971 6059 6058 +3 4748 1243 2348 +3 3406 6060 5267 +3 5557 5556 5588 +3 6241 2589 1245 +3 1245 1351 6241 +3 4309 1247 4743 +3 2482 6071 2644 +3 1246 5939 7022 +3 1248 3464 5910 +3 1249 1250 3204 +3 1250 1304 6138 +3 3696 1610 513 +3 690 1844 5885 +3 4704 6074 1305 +3 6075 3981 282 +3 5866 6077 1537 +3 1537 6077 6078 +3 2640 6078 884 +3 6078 6075 2240 +3 4799 6079 2631 +3 1257 6615 590 +3 1257 1265 6615 +3 6082 3348 1133 +3 7058 5547 4584 +3 6083 3348 1260 +3 6083 5688 1152 +3 6372 3587 5821 +3 5688 6083 2647 +3 734 1394 1599 +3 7254 7253 6027 +3 6936 5349 3260 +3 4920 4159 4076 +3 5215 2075 6901 +3 5259 6085 4690 +3 4420 6807 6578 +3 7179 5176 6087 +3 6087 916 1158 +3 2201 1069 1989 +3 5821 6719 6372 +3 5197 6089 15 +3 1697 2216 3709 +3 15 6089 6204 +3 4720 3740 6361 +3 1266 264 5151 +3 4090 6092 17 +3 1270 2446 1329 +3 4889 6095 1381 +3 1381 6095 6141 +3 4349 6097 6941 +3 538 3691 4875 +3 7244 6360 2892 +3 1272 5373 2056 +3 1274 1211 1552 +3 6099 6100 1043 +3 5499 1599 1394 +3 1276 2561 3133 +3 4261 6100 6098 +3 6667 4782 6101 +3 580 6101 2084 +3 2213 4053 1374 +3 2245 1279 6843 +3 1279 5121 1006 +3 4819 6106 5561 +3 3514 6111 3252 +3 4125 4126 5878 +3 2471 6107 6108 +3 4310 3542 2780 +3 3415 6108 6106 +3 3514 3235 1283 +3 5682 6111 5392 +3 1283 6112 2171 +3 1282 6754 4393 +3 6339 6442 45 +3 6702 6506 924 +3 4491 6981 2114 +3 1699 5693 1366 +3 1585 6116 6902 +3 6400 4844 7461 +3 4803 6118 1766 +3 5650 3966 2211 +3 4067 6579 2493 +3 7091 2034 6506 +3 3243 3884 3251 +3 6661 5887 5886 +3 5782 5783 6363 +3 188 6120 6122 +3 5777 5776 1066 +3 3250 4780 207 +3 4632 4555 3388 +3 3249 6999 4535 +3 2949 6122 6119 +3 6123 5703 2293 +3 5703 6123 6124 +3 6124 6123 6946 +3 6125 6687 901 +3 1907 4303 4709 +3 4208 3536 6959 +3 2391 3246 4746 +3 1317 6126 6128 +3 3953 3952 847 +3 2743 1533 5478 +3 2631 6128 4799 +3 6487 4304 1734 +3 4902 6129 3488 +3 3488 6129 7491 +3 6775 6131 556 +3 2217 3244 4189 +3 5087 7149 3334 +3 1514 6133 2864 +3 2864 6133 6135 +3 985 1712 5201 +3 6696 6135 371 +3 371 6135 6131 +3 1796 1343 5859 +3 2103 5406 1422 +3 825 6139 6129 +3 7491 6139 5031 +3 5031 6139 2858 +3 1342 2794 1993 +3 6066 6504 1484 +3 4554 5075 3239 +3 1205 451 1750 +3 6097 6095 6941 +3 1381 6141 6142 +3 4873 1691 735 +3 7051 6142 6140 +3 6891 6144 2552 +3 6144 6183 1789 +3 5486 5487 1604 +3 5014 6146 1180 +3 4035 896 6899 +3 3675 793 4733 +3 1180 6146 7481 +3 4170 6845 3238 +3 4302 542 4348 +3 5039 1547 3904 +3 4707 6149 361 +3 4407 3725 6883 +3 3514 6598 3235 +3 1088 461 1368 +3 6279 6151 6194 +3 3776 3419 2972 +3 4515 6154 7199 +3 890 5265 3192 +3 7027 6155 4011 +3 4011 6155 6157 +3 6157 6841 2881 +3 6841 6157 6154 +3 123 6158 10 +3 6158 6210 2350 +3 5822 6159 1308 +3 699 6186 1286 +3 5167 1286 2728 +3 393 4989 5924 +3 1060 1561 356 +3 1483 6160 2651 +3 5038 7074 1966 +3 6161 928 1438 +3 3543 2705 2285 +3 3496 6163 6167 +3 3263 464 3042 +3 6054 6167 578 +3 4917 5695 2455 +3 578 6167 6161 +3 2219 1660 4385 +3 6379 6782 1289 +3 7198 2557 2779 +3 5877 3300 1380 +3 3808 1216 3098 +3 6172 6697 296 +3 6173 508 4264 +3 2062 6173 5542 +3 4436 4236 573 +3 152 6513 6339 +3 296 2420 6172 +3 451 994 6175 +3 3981 6077 466 +3 7198 6863 2557 +3 6176 6174 2387 +3 3810 3809 751 +3 7394 6177 6508 +3 7092 2481 3774 +3 60 4026 1137 +3 4547 2322 4534 +3 6178 1292 2655 +3 1292 6178 567 +3 3050 991 723 +3 6182 13 654 +3 13 6182 6183 +3 1964 1267 6812 +3 275 5662 833 +3 2490 3570 5684 +3 6145 6144 5346 +3 1789 2552 6144 +3 5243 6396 6957 +3 2496 2236 6844 +3 699 6922 7170 +3 4076 6257 4920 +3 699 6185 6186 +3 2651 4073 1483 +3 3994 6186 6185 +3 5940 3144 6284 +3 833 5552 275 +3 7071 6187 1017 +3 4198 4070 772 +3 5238 6188 6190 +3 4946 4631 5690 +3 1286 6837 699 +3 925 6190 6187 +3 620 4762 6660 +3 4569 7111 1708 +3 6193 6198 2658 +3 6149 6151 361 +3 6735 2411 1296 +3 6194 6193 6279 +3 5199 855 620 +3 6198 1297 2658 +3 1783 3157 2704 +3 7136 4154 3344 +3 6849 6201 2985 +3 3261 3465 555 +3 3260 6202 6936 +3 6936 6202 6203 +3 5711 6203 4259 +3 4259 6203 6201 +3 6090 6089 1954 +3 3582 2898 2653 +3 5426 2842 2782 +3 15 6204 7030 +3 3224 3225 955 +3 5019 4876 3232 +3 1298 5194 4843 +3 1299 1303 5879 +3 6207 5928 6377 +3 1302 6208 6413 +3 6070 6871 6837 +3 4183 4142 6413 +3 771 6542 2909 +3 4183 6208 2660 +3 1304 6074 2430 +3 1305 1875 4704 +3 1847 1306 2112 +3 2719 6555 6586 +3 1310 7414 2850 +3 5817 6212 2199 +3 311 6468 2208 +3 2912 6213 6585 +3 6585 6213 6216 +3 2031 7218 258 +3 6950 6216 532 +3 532 6216 6212 +3 1311 6819 1317 +3 5846 3029 963 +3 3680 2220 426 +3 7376 4426 1711 +3 3146 3333 3986 +3 2313 6218 421 +3 7198 2779 1894 +3 7198 1894 856 +3 421 6218 6217 +3 5672 6219 6143 +3 1711 6219 6217 +3 1391 3242 4974 +3 4210 4169 3754 +3 3451 6220 5525 +3 544 6221 2032 +3 1684 3376 5154 +3 6442 6221 45 +3 3221 24 2142 +3 45 6221 98 +3 2206 5042 1723 +3 6373 6478 363 +3 5511 6223 4817 +3 5503 4817 6223 +3 6224 2055 5538 +3 6606 6225 2666 +3 4501 3719 1617 +3 2666 4749 6606 +3 4317 3115 5668 +3 2394 6227 6229 +3 7231 6229 7517 +3 6229 6226 7517 +3 6232 3255 202 +3 4001 6232 5317 +3 1810 629 5781 +3 1322 7489 6322 +3 5443 6301 6863 +3 1322 834 7489 +3 7197 6233 316 +3 5993 5995 479 +3 6940 4922 2803 +3 3329 1765 4169 +3 3417 6234 6357 +3 896 694 3683 +3 6299 6237 4549 +3 5535 3092 1741 +3 4438 3275 227 +3 2753 6240 32 +3 2358 3364 3271 +3 32 6240 2672 +3 6552 6365 5305 +3 3025 1324 2669 +3 6645 4369 3170 +3 6529 6243 6948 +3 3995 6244 5134 +3 5134 6244 6245 +3 7164 6245 5992 +3 5992 6245 6243 +3 7088 6230 5943 +3 4375 6575 6586 +3 5099 3524 2436 +3 2621 2826 3594 +3 1327 3533 4498 +3 2673 3640 88 +3 301 6248 7117 +3 81 4514 1747 +3 3125 3038 6171 +3 7102 1400 6393 +3 1252 6582 2580 +3 3699 3698 1761 +3 4731 6249 6251 +3 631 3496 1186 +3 5731 6251 2341 +3 2341 6251 6248 +3 2995 944 3001 +3 2850 6253 2112 +3 1804 3670 3208 +3 4055 7332 6632 +3 4334 3861 2203 +3 2785 6575 4375 +3 1334 2674 5158 +3 6038 3628 3724 +3 7336 4411 4410 +3 670 5753 1333 +3 298 3972 2202 +3 1333 6256 4807 +3 5110 2098 4807 +3 1331 5110 6256 +3 5823 6258 2009 +3 2009 6258 6925 +3 2782 2492 5426 +3 3056 6259 3920 +3 4055 6621 7332 +3 4713 6260 3317 +3 3317 6260 6614 +3 1335 2510 1984 +3 1335 7453 2510 +3 1337 4553 7361 +3 5393 5352 545 +3 5164 6868 6969 +3 1337 1341 6263 +3 3974 62 5143 +3 4342 6263 5588 +3 5588 6263 2679 +3 1872 1340 6253 +3 265 7036 4674 +3 2477 5338 3815 +3 2678 2112 6253 +3 2937 7474 7477 +3 648 6270 4576 +3 5129 3614 1004 +3 5129 6271 7369 +3 6093 7127 5281 +3 3397 6272 5936 +3 6704 889 5135 +3 3211 2002 2825 +3 2576 4149 6490 +3 1345 6274 319 +3 6773 4508 3191 +3 1348 5260 2725 +3 1349 6280 2643 +3 1351 6066 6241 +3 1715 62 3974 +3 1347 3171 6280 +3 2170 1611 3490 +3 5440 4042 448 +3 3795 5206 6875 +3 6899 896 945 +3 3704 3241 4861 +3 2168 6283 448 +3 6285 3167 3369 +3 3167 6285 6281 +3 436 1449 2741 +3 3546 6286 4554 +3 5075 5076 3083 +3 5397 6288 6290 +3 6201 6290 4259 +3 4259 6290 6286 +3 4927 4929 905 +3 5835 6589 6086 +3 5077 6292 7489 +3 7489 6292 6322 +3 3204 922 1249 +3 7378 1452 4797 +3 5989 4105 1396 +3 2993 4143 6868 +3 5733 5735 6565 +3 3622 3623 25 +3 76 1743 2812 +3 4549 6298 6299 +3 4233 6299 2473 +3 4312 6607 1509 +3 2473 6299 6295 +3 7384 6302 7281 +3 626 5032 2164 +3 4188 1623 792 +3 3091 6303 5024 +3 5531 5501 6589 +3 3931 2696 614 +3 5024 6303 1353 +3 5769 6304 5961 +3 5961 6304 2266 +3 1354 7202 1991 +3 652 2265 3679 +3 7202 1354 6307 +3 6961 6308 6293 +3 6293 6308 2683 +3 5893 3422 1700 +3 4708 4532 2029 +3 1359 6308 7325 +3 1142 4059 4026 +3 7084 6988 1966 +3 4046 3531 6983 +3 5358 5357 7214 +3 4552 6316 6317 +3 3809 6317 751 +3 3304 2621 5250 +3 6729 1154 96 +3 2254 2576 6490 +3 6104 3823 3199 +3 6813 2865 972 +3 2955 2835 2689 +3 751 6317 6314 +3 3595 740 69 +3 5697 6319 6612 +3 6612 6319 6318 +3 3197 1301 1684 +3 6321 1908 1745 +3 318 5156 2742 +3 417 6292 4784 +3 5017 703 3114 +3 6901 7178 4485 +3 2632 6323 4311 +3 6323 6324 4311 +3 715 6324 2424 +3 414 2424 6324 +3 4793 1420 1046 +3 6032 4485 4545 +3 1280 6028 2147 +3 9 2935 237 +3 2832 6328 4590 +3 3313 5291 3190 +3 5298 4709 2661 +3 7104 7115 7112 +3 3750 4590 6328 +3 3314 5016 3378 +3 3378 5016 135 +3 1220 4597 1369 +3 1369 6331 1395 +3 3446 2618 1821 +3 1392 6331 1166 +3 6331 1370 630 +3 4300 6332 3182 +3 4164 6334 1818 +3 1818 3061 4164 +3 2966 2951 1358 +3 7388 401 724 +3 4461 3188 6435 +3 5070 2733 7368 +3 5070 7372 7370 +3 6943 4763 808 +3 6954 6617 9 +3 7368 2733 3934 +3 1512 4861 6962 +3 6396 94 231 +3 6674 6340 4053 +3 4053 6340 1374 +3 1078 4520 5067 +3 231 2875 6396 +3 116 1372 6342 +3 2667 6773 4996 +3 4296 6342 2965 +3 927 3184 4361 +3 1373 2946 5246 +3 1375 6340 6515 +3 5885 4372 1097 +3 6345 192 1740 +3 7471 7304 6348 +3 7466 6871 6070 +3 6257 7013 4155 +3 5750 6348 3409 +3 3409 6348 1822 +3 1913 1376 5034 +3 4538 4539 6667 +3 6352 2527 1376 +3 4131 4130 1067 +3 4551 6352 6349 +3 2098 6353 722 +3 7099 5687 722 +3 5299 6356 5461 +3 6237 6234 4549 +3 3417 6357 6563 +3 678 7228 2963 +3 4636 6359 2082 +3 2082 6359 6362 +3 3383 7219 2790 +3 3308 6362 6358 +3 6358 5529 3308 +3 987 3178 3977 +3 1695 5543 351 +3 4133 4134 1521 +3 4787 6367 6368 +3 1698 6368 5540 +3 5952 1617 6793 +3 6368 6366 5540 +3 5411 5410 4997 +3 1108 4248 365 +3 375 6371 4827 +3 4745 6371 6886 +3 6886 6371 6369 +3 4320 4505 2692 +3 1377 270 3548 +3 1378 6375 3697 +3 2028 2069 2484 +3 4449 4450 4350 +3 6377 6378 6207 +3 2998 672 2623 +3 6207 3588 5879 +3 1941 7171 2347 +3 1449 5499 1696 +3 18 7464 1523 +3 6782 6379 6170 +3 924 6657 6702 +3 2192 6380 3316 +3 1383 3316 6380 +3 2026 924 6442 +3 2808 5837 3728 +3 2693 5704 781 +3 1384 5907 644 +3 3451 5525 547 +3 4844 6400 3751 +3 3736 6665 6657 +3 1591 6435 6996 +3 5228 6384 2381 +3 6384 1389 2695 +3 3175 1691 2140 +3 1385 6042 4403 +3 1387 6386 598 +3 7261 7456 3813 +3 7 18 4461 +3 1388 6386 1389 +3 1389 4298 1388 +3 1853 1100 6030 +3 5406 6388 5387 +3 6388 1393 1860 +3 5652 5859 1343 +3 5652 6390 5264 +3 1395 1220 1369 +3 5092 5258 2113 +3 1220 1395 1393 +3 2654 3907 1400 +3 1397 2232 6447 +3 6393 2207 7102 +3 516 3408 1290 +3 2476 236 2698 +3 5953 6397 4950 +3 4950 6397 6733 +3 6764 6398 3766 +3 5280 1713 844 +3 1561 353 7524 +3 7219 7141 5589 +3 1616 6402 1308 +3 4502 6403 2156 +3 7333 6665 3736 +3 2156 6403 6713 +3 1403 3624 1472 +3 3216 510 1738 +3 4802 6410 3209 +3 5954 5953 4950 +3 5943 7473 7085 +3 6413 5928 1302 +3 5928 6413 1405 +3 2200 4509 1409 +3 1409 6416 299 +3 6416 1405 4156 +3 4156 2374 6416 +3 4352 5128 1775 +3 1413 4981 2626 +3 2796 3168 42 +3 4431 6417 362 +3 2899 2044 1415 +3 1415 6418 408 +3 5091 6008 1084 +3 1417 2064 6420 +3 6402 6702 1308 +3 748 6422 4634 +3 4634 6422 6424 +3 2118 6424 6421 +3 1342 6427 809 +3 1086 4712 6430 +3 3594 4672 212 +3 2025 6747 2022 +3 6432 6430 4712 +3 353 6164 2290 +3 1418 619 625 +3 7290 6433 1425 +3 2023 5479 5145 +3 6436 5210 233 +3 4007 4805 3910 +3 5210 5209 888 +3 1419 5926 5209 +3 4898 7341 3867 +3 2617 2443 6005 +3 2636 6730 627 +3 6915 2936 908 +3 6360 6724 2892 +3 2695 6439 2381 +3 241 4258 3163 +3 1469 6192 1332 +3 5227 3076 4581 +3 2661 4709 4303 +3 1407 6440 6441 +3 3946 6441 2061 +3 6441 6439 522 +3 6153 1433 6360 +3 2164 4984 626 +3 1432 6444 5915 +3 1911 7024 2783 +3 5916 6012 1175 +3 1827 1280 2147 +3 2591 3611 1647 +3 6156 3477 692 +3 6724 6360 1431 +3 6809 6810 10 +3 3473 639 3846 +3 6626 6747 2024 +3 4866 5785 1516 +3 5736 5737 5989 +3 1406 3062 6376 +3 6084 6842 3159 +3 3442 6449 2591 +3 6449 6450 3611 +3 3667 6450 2730 +3 2730 6450 6448 +3 6508 6451 3752 +3 4299 2670 3263 +3 2137 5754 2316 +3 2595 5695 3310 +3 2515 6997 3158 +3 3083 6014 1673 +3 7139 4092 3134 +3 2082 6452 6453 +3 4636 4637 205 +3 2048 6453 6451 +3 4796 535 216 +3 5442 1940 1838 +3 6054 2642 3862 +3 7251 1470 6093 +3 4823 4819 5561 +3 1439 6457 2559 +3 5922 6865 5762 +3 6457 578 6161 +3 731 4664 3153 +3 4169 1991 5515 +3 5800 1996 6831 +3 2526 3147 22 +3 6462 1442 3578 +3 5724 3754 2478 +3 1442 2226 5797 +3 1440 149 6462 +3 1447 3865 5504 +3 3814 1506 6700 +3 422 6465 2715 +3 923 6815 6833 +3 4843 6467 311 +3 5473 6287 2252 +3 6468 5086 342 +3 2314 1899 1805 +3 3055 1499 6789 +3 5086 6468 1959 +3 6471 822 5569 +3 6471 6467 1451 +3 5679 6547 2521 +3 2151 6815 923 +3 337 1344 507 +3 5679 5073 2926 +3 1454 3842 195 +3 3727 5985 294 +3 327 6475 4427 +3 5296 6475 4426 +3 4737 3537 1067 +3 6817 1534 6503 +3 6832 6815 2078 +3 7409 4124 3774 +3 6477 6480 187 +3 2319 6480 1193 +3 1193 6480 6476 +3 6868 6481 2993 +3 5661 6483 7367 +3 7367 6483 2073 +3 5994 3729 7353 +3 3407 6484 7201 +3 366 2705 3150 +3 6134 2955 2449 +3 6663 6485 300 +3 7301 4326 6016 +3 300 6485 6056 +3 5349 5350 4298 +3 4764 3921 1078 +3 5534 6488 3518 +3 2449 6127 6134 +3 3518 6488 6489 +3 6203 6489 6936 +3 6936 6489 6486 +3 332 4454 4191 +3 6492 3847 873 +3 3847 6492 6493 +3 5539 5413 5066 +3 1607 3543 2285 +3 6493 6491 1458 +3 2758 3740 214 +3 3399 6494 3668 +3 7136 3344 5504 +3 2668 3677 3573 +3 7086 5552 5341 +3 3309 3283 3083 +3 5191 6496 1461 +3 2810 5738 1460 +3 6498 4970 4971 +3 4971 4970 2287 +3 1461 4886 6498 +3 2303 71 7496 +3 6410 6500 3041 +3 1739 6501 144 +3 144 6501 7252 +3 1464 2772 1470 +3 4804 4364 168 +3 7185 2772 1465 +3 1982 2856 1779 +3 6605 1058 1465 +3 7427 6437 5215 +3 4029 3543 2720 +3 778 4008 1471 +3 6542 5803 4921 +3 4760 934 3761 +3 7402 1957 3893 +3 934 4760 4231 +3 6451 6177 2048 +3 3438 6509 6619 +3 5922 1744 5998 +3 6619 6509 6510 +3 3435 6510 3752 +3 3752 6510 6508 +3 2930 6512 3377 +3 6512 1765 3329 +3 7473 5943 4956 +3 6063 6840 6923 +3 1474 771 1943 +3 7366 3865 6465 +3 2306 3138 952 +3 184 2464 3520 +3 1375 6515 2721 +3 5803 6542 6600 +3 6600 1731 5803 +3 2721 124 1375 +3 1473 6514 1014 +3 1977 6840 6063 +3 667 5089 1981 +3 5066 2045 6000 +3 6000 2045 846 +3 6794 3452 5472 +3 4992 3330 3462 +3 3565 3566 6081 +3 2458 6522 6524 +3 4643 6524 2989 +3 6361 2758 2590 +3 6423 7473 3422 +3 2989 6524 6519 +3 1561 5158 353 +3 1155 6525 651 +3 5521 3217 2075 +3 4791 4790 3497 +3 2192 3316 5526 +3 642 6528 5325 +3 1936 6606 4749 +3 5325 5324 2104 +3 565 1969 1025 +3 5455 2571 2187 +3 4767 6529 4328 +3 4328 6529 7307 +3 1911 3983 5818 +3 5103 6530 6948 +3 3031 6531 1476 +3 6532 5536 1475 +3 5536 6532 6533 +3 4749 4678 1936 +3 1934 6282 864 +3 7037 6006 7518 +3 2458 3927 1281 +3 4271 5246 1679 +3 4058 6535 807 +3 807 6535 6536 +3 6550 1523 2619 +3 4447 3929 5619 +3 4194 5744 1315 +3 3695 6536 3034 +3 2021 6840 576 +3 3034 6536 6534 +3 1174 6537 6051 +3 1686 6538 7230 +3 160 6539 2485 +3 817 665 2608 +3 2191 6296 1737 +3 4761 6540 4212 +3 3475 6333 2253 +3 3634 7507 1618 +3 4149 6541 6490 +3 5794 5795 1761 +3 6063 6543 1977 +3 5321 6544 3075 +3 6544 6541 5117 +3 6545 6143 3507 +3 5200 6548 1294 +3 1294 6548 6712 +3 2727 6986 315 +3 1523 4461 18 +3 1423 7410 2389 +3 6235 6401 2181 +3 5117 6541 2270 +3 4457 6551 537 +3 2305 4863 2000 +3 2873 6950 7011 +3 6701 6554 5225 +3 2904 5244 2181 +3 5353 7404 3325 +3 3893 1957 2418 +3 5878 4094 3128 +3 1459 6885 6057 +3 5906 444 2978 +3 1957 7378 2418 +3 6086 2696 4020 +3 1478 3398 553 +3 6262 5435 5949 +3 1480 1832 4774 +3 7512 7141 7219 +3 7337 7012 3302 +3 1485 5152 6196 +3 5576 6988 4199 +3 2652 6559 6560 +3 6403 6560 2056 +3 2056 6560 6558 +3 6216 5468 6585 +3 7227 4324 7211 +3 5830 6561 4484 +3 4919 6562 5904 +3 2821 697 3646 +3 5904 6562 6563 +3 7330 5751 3086 +3 6356 6357 5461 +3 3417 6563 6561 +3 5620 5621 1479 +3 4721 142 6130 +3 4513 6566 7196 +3 2638 2532 5383 +3 6421 4117 2118 +3 3236 1090 3666 +3 3149 6946 6123 +3 6567 1623 1190 +3 7117 321 315 +3 2981 3709 1490 +3 1490 1572 4814 +3 6454 6091 7110 +3 4575 2446 1571 +3 1571 3416 4575 +3 2689 2449 2955 +3 532 6952 6950 +3 3939 6549 7407 +3 6546 6572 5849 +3 1495 5850 2257 +3 5467 6572 1569 +3 5072 6251 5731 +3 7192 6952 532 +3 6573 2338 3077 +3 5218 7011 2463 +3 15 7030 4004 +3 975 1326 6574 +3 4320 3207 1327 +3 4487 6576 3230 +3 6576 6577 2129 +3 1726 4411 2769 +3 4214 6577 6048 +3 314 5958 6048 +3 2746 4303 1907 +3 3284 1748 6972 +3 6759 6725 177 +3 6578 1252 4420 +3 4759 405 1497 +3 4759 6582 6583 +3 5464 6583 2063 +3 2063 6723 5464 +3 6584 4958 7451 +3 4958 6584 6588 +3 3832 3515 1642 +3 6588 5057 7425 +3 5609 1501 948 +3 1507 5832 948 +3 728 5838 1505 +3 1505 6592 1873 +3 5950 1339 2952 +3 903 3212 7248 +3 339 752 4170 +3 7413 559 2227 +3 1503 559 6592 +3 3039 6595 4657 +3 1735 7327 6102 +3 4657 6595 1628 +3 7437 1262 2687 +3 2037 4100 2016 +3 4061 6596 1629 +3 3252 6597 3514 +3 3566 6598 6081 +3 6081 6598 6599 +3 1210 3176 696 +3 4773 6599 4593 +3 4593 6599 6597 +3 6780 6601 739 +3 5756 7472 486 +3 1321 3692 4251 +3 6211 5288 6647 +3 6602 6603 995 +3 4763 6943 3815 +3 4797 5602 7378 +3 6205 6204 2840 +3 869 6603 6601 +3 5229 5230 4215 +3 2838 6604 73 +3 73 6604 2072 +3 7060 7065 2844 +3 6605 2076 5285 +3 4781 3576 4780 +3 4838 3450 2703 +3 4781 292 4263 +3 77 5892 3664 +3 7070 6610 4034 +3 4034 6610 6613 +3 3163 6611 241 +3 1436 2597 2247 +3 6611 6610 241 +3 6259 6260 3920 +3 4440 4649 5507 +3 1692 3802 1597 +3 1880 5924 2379 +3 4797 4753 2981 +3 3317 6614 6616 +3 4645 960 7087 +3 6049 694 864 +3 4820 1452 4216 +3 4567 6616 2104 +3 2104 6616 6613 +3 7501 7060 1408 +3 4995 6550 6618 +3 373 7062 7060 +3 4603 3478 516 +3 3039 6622 6623 +3 6623 1788 3039 +3 5005 4777 1371 +3 4697 2062 4272 +3 6789 1499 2247 +3 5005 6623 6620 +3 4400 5509 1769 +3 6993 7138 708 +3 2571 3055 6789 +3 3058 6624 4459 +3 4204 2284 1517 +3 1517 6627 5217 +3 6918 6627 1181 +3 6625 1181 6627 +3 6628 7475 1232 +3 3059 6629 7156 +3 7156 6629 6631 +3 2326 3120 7173 +3 3748 3745 5911 +3 3215 6631 6628 +3 2242 3470 302 +3 5829 5720 6821 +3 5829 6634 6635 +3 6127 2778 7402 +3 6423 5893 2397 +3 5905 6635 6414 +3 6414 6635 6633 +3 1436 1499 4421 +3 3351 6638 3301 +3 3324 3326 3796 +3 1200 6639 6640 +3 2242 3876 6640 +3 201 6640 6638 +3 4369 6645 2962 +3 4722 6606 5485 +3 1301 3376 1684 +3 644 5235 3971 +3 6538 1087 6051 +3 3881 6646 1021 +3 844 1713 3829 +3 1021 6646 6648 +3 5271 5273 5904 +3 4601 664 4651 +3 1911 6521 3607 +3 3170 6648 6645 +3 5282 4157 4833 +3 6650 6651 681 +3 4768 2398 6651 +3 574 4625 1518 +3 574 6651 6650 +3 2196 3534 1520 +3 5825 6655 3129 +3 4348 5244 5450 +3 135 257 899 +3 5876 2249 3079 +3 5016 5757 5343 +3 1056 7129 866 +3 5094 3694 892 +3 2762 1524 2731 +3 2731 343 2762 +3 208 3894 1525 +3 1045 4360 1033 +3 1528 3460 4703 +3 102 7128 11 +3 1529 5870 3526 +3 2158 6662 300 +3 6663 300 1531 +3 4456 6663 1883 +3 7129 125 1963 +3 1883 6663 2736 +3 4460 7013 7244 +3 1650 3663 6313 +3 177 5684 6759 +3 2318 2671 940 +3 6011 7062 373 +3 3891 6666 2649 +3 2649 6666 7483 +3 6987 6669 633 +3 5796 6670 4053 +3 6670 771 6674 +3 6674 771 1474 +3 7094 1535 3747 +3 5236 6678 5478 +3 5478 6678 2743 +3 1536 6040 6924 +3 6680 5513 2434 +3 1538 4835 3165 +3 5664 5402 1498 +3 3922 293 2079 +3 249 1552 1094 +3 6934 2060 2870 +3 2079 2971 3922 +3 1654 4346 5475 +3 3547 3546 4554 +3 4068 6684 6682 +3 4999 702 1610 +3 5084 5083 2622 +3 3232 6686 1540 +3 3182 6689 4300 +3 872 5027 319 +3 5549 6691 283 +3 1540 283 6691 +3 1985 5398 4967 +3 6637 3850 4117 +3 1795 5444 4329 +3 4956 5943 6230 +3 1795 6694 6695 +3 5034 3492 1913 +3 5528 5530 3862 +3 291 6693 2468 +3 4322 6696 1072 +3 1542 5614 638 +3 2659 3028 2720 +3 2244 6792 3111 +3 5975 6698 6699 +3 5896 6699 371 +3 371 6699 6696 +3 3609 4194 3007 +3 2185 6792 7085 +3 6871 6701 5763 +3 6554 6701 1323 +3 6988 5576 1938 +3 4438 6703 6709 +3 6550 6551 1523 +3 5152 5858 6690 +3 6792 2185 759 +3 5152 6690 2474 +3 3087 2867 2744 +3 4296 3087 116 +3 1545 6709 6705 +3 537 6703 1544 +3 4494 5222 7139 +3 4438 6709 2744 +3 4096 6800 7038 +3 601 6711 1051 +3 1051 6711 6710 +3 6547 6548 3924 +3 2156 6713 6405 +3 2433 6337 5974 +3 6405 1549 3117 +3 5556 4342 5588 +3 3971 2346 644 +3 2394 6753 3103 +3 1665 6715 279 +3 7149 5087 3929 +3 1704 938 4955 +3 5373 6715 2056 +3 2056 6715 6403 +3 4184 4181 343 +3 3034 4270 3084 +3 3695 3694 5094 +3 61 6720 7445 +3 5834 1942 1620 +3 6479 2657 112 +3 2019 7091 5834 +3 3821 6725 5029 +3 5819 356 696 +3 3707 1558 2138 +3 6118 7113 4755 +3 2139 2745 5844 +3 5560 1558 1211 +3 262 6642 7077 +3 6690 2770 2474 +3 627 6730 7275 +3 5067 485 6117 +3 7275 5605 7279 +3 5816 1134 7146 +3 4474 4475 5161 +3 6398 6397 3766 +3 6850 468 6863 +3 4950 6733 6734 +3 7162 6734 5630 +3 5630 6734 6731 +3 6079 6737 2631 +3 376 6408 5079 +3 468 5443 6863 +3 3332 6739 6740 +3 6189 7140 2888 +3 3649 3432 1013 +3 1614 6740 6737 +3 4880 6704 5135 +3 7301 3334 639 +3 3626 6424 2118 +3 4831 6828 881 +3 4561 3100 3252 +3 7140 6189 1817 +3 410 2648 246 +3 6742 922 3204 +3 5470 6085 4688 +3 7278 4306 1919 +3 2015 5071 505 +3 679 2183 666 +3 5891 6745 5483 +3 3849 6746 5335 +3 5335 6746 6748 +3 6412 6748 3439 +3 3439 6748 6745 +3 1095 5979 6797 +3 2846 2031 258 +3 6750 1536 6924 +3 6555 2719 2031 +3 2613 3114 3767 +3 2847 1929 6752 +3 6752 6750 3109 +3 3154 1472 172 +3 3174 6753 4542 +3 4638 6755 5663 +3 5663 6755 6756 +3 6229 6756 2394 +3 2394 6756 6753 +3 6725 6759 5029 +3 5029 6759 1565 +3 7218 2719 2100 +3 119 5926 2286 +3 5589 809 2003 +3 1398 3527 7293 +3 1569 3253 4683 +3 1882 1933 1836 +3 4435 6759 5684 +3 2282 2194 2399 +3 6974 648 3284 +3 4303 2569 2661 +3 4440 4932 2616 +3 7350 6764 6593 +3 4487 6765 677 +3 677 6765 6835 +3 7159 7000 2157 +3 3097 3098 6337 +3 4157 6768 4833 +3 6719 5821 947 +3 2635 6769 794 +3 794 6769 6866 +3 343 4181 3672 +3 2286 7222 119 +3 1571 2726 3416 +3 4305 4414 287 +3 4808 6772 4812 +3 7146 1134 3213 +3 3530 6774 556 +3 2334 1908 6321 +3 869 5510 3095 +3 556 6774 6775 +3 7237 7222 382 +3 125 7428 1797 +3 5898 6775 6565 +3 6565 6775 6772 +3 4275 6494 4751 +3 188 5777 1577 +3 5990 6777 1446 +3 1221 1253 5403 +3 1578 1446 6777 +3 1855 1856 6778 +3 5578 5577 5469 +3 739 6779 6780 +3 6601 5510 869 +3 6076 6780 6778 +3 5778 6781 6419 +3 1925 6722 7077 +3 6736 6781 2161 +3 6737 6783 1614 +3 6784 5651 395 +3 7156 3748 3093 +3 5651 6784 6785 +3 3088 3052 3305 +3 1091 6785 2738 +3 5323 6786 2848 +3 2751 6786 1581 +3 6885 1867 1582 +3 1582 6791 3302 +3 3302 6791 746 +3 1581 746 6791 +3 5472 2467 5434 +3 2344 6793 1617 +3 6781 6793 6419 +3 5434 6794 5472 +3 2495 4194 5509 +3 3713 1241 3092 +3 6219 6796 421 +3 6474 6472 538 +3 6799 1344 251 +3 2533 5250 2621 +3 917 6796 5672 +3 7287 6801 2106 +3 4025 7202 6303 +3 2891 5888 7019 +3 6802 7179 6116 +3 7179 6802 860 +3 2915 6803 197 +3 197 6803 6801 +3 5633 2386 5724 +3 7129 4447 7428 +3 5541 6804 5855 +3 32 5855 2753 +3 103 3817 4864 +3 103 6806 3817 +3 925 4084 3089 +3 1482 6806 35 +3 2744 3085 4438 +3 35 6806 2752 +3 2063 1588 6723 +3 2670 2826 464 +3 5546 3643 7519 +3 1589 6166 313 +3 1589 2754 6166 +3 2350 6809 10 +3 7393 6810 5046 +3 1799 4318 6389 +3 5046 6810 7448 +3 800 3236 3916 +3 6811 6812 2271 +3 3032 7237 4052 +3 3125 6814 2760 +3 5613 5455 1477 +3 6718 3084 747 +3 6814 1592 5204 +3 3125 6171 4501 +3 5784 3022 3082 +3 2418 7141 3893 +3 1592 5186 6766 +3 1593 6814 5314 +3 2012 5109 2665 +3 6743 6818 5160 +3 3082 2898 5784 +3 5160 6818 1594 +3 2925 6819 6649 +3 6346 3968 4410 +3 1594 6649 6819 +3 2904 4289 1601 +3 3275 4438 3085 +3 238 2242 302 +3 151 2242 238 +3 5379 6668 5377 +3 4583 5010 6823 +3 5484 3672 3197 +3 343 6824 2762 +3 3494 6825 2315 +3 2221 7380 4032 +3 6827 7380 1598 +3 4252 4250 5844 +3 3080 670 1333 +3 4169 4210 3329 +3 5668 6827 2763 +3 4222 4223 558 +3 6044 6829 3449 +3 4588 6829 6372 +3 2761 149 1440 +3 1906 7185 1058 +3 3247 2904 1601 +3 1745 4048 6321 +3 4602 4262 1893 +3 2722 7494 1921 +3 644 2346 3746 +3 2004 5431 3833 +3 5804 903 4831 +3 890 2528 5265 +3 6969 6868 2033 +3 6764 6765 6593 +3 5308 5307 1176 +3 3160 6838 6839 +3 5798 5799 3439 +3 3766 6839 6835 +3 3554 1696 4924 +3 4188 4882 1623 +3 4170 3238 339 +3 3535 6637 4966 +3 3345 3509 6738 +3 3014 6847 4650 +3 4014 6848 6069 +3 6290 6849 5397 +3 6510 6851 6619 +3 5122 3769 581 +3 6619 6851 6852 +3 5638 5636 3627 +3 2985 6852 6849 +3 7392 7294 2886 +3 2634 6854 6855 +3 750 2272 2182 +3 3231 6855 2205 +3 2205 6855 6853 +3 3175 3174 4542 +3 24 6856 2142 +3 5137 7211 4324 +3 169 1111 2066 +3 4535 5137 3249 +3 2210 4921 5803 +3 2510 7453 2857 +3 5719 6722 6482 +3 1691 6859 2140 +3 3125 5314 6814 +3 903 5804 898 +3 6321 6860 5178 +3 2001 4699 2297 +3 6010 5330 6162 +3 5346 6862 1606 +3 1604 4280 6200 +3 4324 7227 6050 +3 1890 5115 7446 +3 1605 6866 6768 +3 6768 6769 4833 +3 6236 4031 1044 +3 1606 794 6866 +3 1611 6870 234 +3 1011 756 5568 +3 234 6688 5339 +3 5185 3081 4859 +3 1201 2131 6867 +3 942 6874 1671 +3 7077 1120 199 +3 942 1671 1619 +3 1748 2853 6164 +3 7153 6875 4887 +3 6915 6438 6876 +3 7513 2998 4882 +3 2437 6877 2517 +3 2517 6877 1456 +3 50 6402 6878 +3 6810 6880 10 +3 5725 5305 3801 +3 10 6880 123 +3 1619 4028 942 +3 1619 1833 4028 +3 4205 5804 4757 +3 6052 1132 2590 +3 6542 4921 2909 +3 6898 6881 3741 +3 3741 6881 6893 +3 4633 4932 5507 +3 2968 6556 3383 +3 2477 3242 2178 +3 4810 4079 493 +3 709 6890 6891 +3 6891 2552 709 +3 3301 3324 3060 +3 5757 6692 4341 +3 4127 3993 3730 +3 5330 6891 6162 +3 6162 6891 6889 +3 6881 1854 1664 +3 3626 2118 4396 +3 4341 6148 6795 +3 4179 4757 5804 +3 511 7302 2006 +3 2124 2199 6212 +3 6892 1973 623 +3 3829 3830 844 +3 511 3749 3000 +3 6881 6898 2773 +3 352 3402 1207 +3 2773 1854 6881 +3 2119 4285 7200 +3 3364 2358 3340 +3 3364 6904 6907 +3 7032 1423 6102 +3 5316 7426 4649 +3 4868 7072 3056 +3 5479 3898 6197 +3 6562 6905 4484 +3 4484 6905 6907 +3 957 4496 5326 +3 5615 6907 6904 +3 6904 4260 5615 +3 6185 7170 1064 +3 6925 6908 3956 +3 3956 6908 7142 +3 6523 7045 3950 +3 3836 6910 6911 +3 2700 6911 5872 +3 6266 2691 2639 +3 2247 7007 6789 +3 5872 6911 2713 +3 6912 1622 4702 +3 6916 2936 1622 +3 3481 6916 2834 +3 2834 6916 2979 +3 5188 3448 5466 +3 6155 6917 7199 +3 4060 7386 3560 +3 1517 5217 4944 +3 5042 2206 2070 +3 1356 6918 5060 +3 1935 2897 3906 +3 4586 2924 2325 +3 1142 4026 60 +3 4935 6920 616 +3 6929 6921 3956 +3 3956 6921 6925 +3 6908 6258 6523 +3 629 2952 5781 +3 2009 6925 6920 +3 2070 7348 5042 +3 1794 2677 5929 +3 6612 6927 6928 +3 5129 7369 7348 +3 3377 6928 6926 +3 6102 7327 7032 +3 5900 6929 6027 +3 5612 6930 6428 +3 6428 6930 7144 +3 1625 265 6586 +3 3740 6093 1470 +3 2811 6932 2598 +3 2598 6932 6933 +3 7373 6933 1293 +3 1293 6933 6931 +3 6272 6271 5936 +3 5894 6934 7316 +3 2718 5188 3409 +3 1742 2059 2869 +3 1628 6596 4099 +3 1499 1436 2247 +3 5730 6939 2774 +3 3230 3958 1840 +3 6765 6942 6593 +3 7026 6944 5401 +3 3818 1632 3149 +3 6946 3255 6124 +3 6947 2135 1587 +3 2658 6947 2228 +3 2397 2919 5508 +3 1268 960 5253 +3 2228 6947 2776 +3 1666 1634 1636 +3 1636 5466 1666 +3 5750 6951 6399 +3 1635 1854 2120 +3 1970 117 2786 +3 2444 1735 4274 +3 2553 6520 2768 +3 2444 4486 1735 +3 2120 2122 1635 +3 3282 7418 5555 +3 7421 7471 7221 +3 5336 5606 1638 +3 4762 1638 6953 +3 6917 6954 7199 +3 4515 4514 81 +3 492 6955 237 +3 4404 4424 454 +3 7391 6956 2935 +3 501 3296 3047 +3 237 2935 6956 +3 6920 6958 2009 +3 7081 6960 6293 +3 6293 6960 6961 +3 6016 7450 7301 +3 6308 4314 7325 +3 4834 6961 6958 +3 3241 6962 4861 +3 2599 4772 132 +3 4831 881 4179 +3 3185 3187 5129 +3 1498 6964 6966 +3 5667 5534 3518 +3 802 6966 6962 +3 2557 6967 6970 +3 2843 1156 3630 +3 4020 838 7364 +3 3303 5443 2335 +3 704 3558 5240 +3 1521 4134 6967 +3 2296 3286 575 +3 7442 7421 132 +3 4402 6971 3303 +3 4410 4411 6346 +3 4831 4179 5804 +3 1999 7306 81 +3 2768 6744 2553 +3 5624 3521 6621 +3 7223 6399 1851 +3 1643 1748 6164 +3 4202 6974 6975 +3 1706 6975 670 +3 3026 6354 7119 +3 6975 6972 5753 +3 6978 4650 3553 +3 5542 3647 474 +3 7311 7493 7264 +3 557 5040 4360 +3 2884 6979 5610 +3 1732 6980 265 +3 265 6980 7036 +3 3654 3655 6294 +3 5546 672 2998 +3 4522 4521 7214 +3 2727 6985 6986 +3 315 6986 7117 +3 6986 6984 301 +3 6669 5612 6428 +3 226 6987 7028 +3 7481 6989 633 +3 1644 3032 4052 +3 5175 2939 6998 +3 4585 6992 2964 +3 2964 6992 7503 +3 7138 6993 628 +3 2175 4176 1767 +3 628 6993 3722 +3 5232 6995 3189 +3 2174 5508 2919 +3 27 1646 6997 +3 3159 6997 6084 +3 2115 7001 1515 +3 6976 2368 5950 +3 3443 1648 7003 +3 4069 7003 6364 +3 6701 7466 1323 +3 1648 7005 2712 +3 7099 7005 2781 +3 1869 3515 1430 +3 905 3598 2173 +3 2781 154 7099 +3 7433 7006 4212 +3 4212 7006 5966 +3 5523 7008 5356 +3 1785 1649 717 +3 2416 1649 1651 +3 4485 7178 3846 +3 1651 7016 6443 +3 5653 1652 2942 +3 2964 7503 7493 +3 2033 1556 1918 +3 1858 7017 2107 +3 2107 7017 7145 +3 6911 4232 3836 +3 1658 7020 622 +3 7021 5500 4469 +3 5500 7021 7023 +3 1918 7004 5903 +3 1563 1309 7025 +3 7023 7020 1656 +3 6521 2783 6520 +3 7025 1309 1656 +3 671 3354 3040 +3 7025 7421 1563 +3 5370 7026 4011 +3 6917 7027 263 +3 263 7027 5318 +3 4657 6105 3039 +3 6989 6987 633 +3 226 7028 6429 +3 5259 521 153 +3 5458 7029 622 +3 622 7029 1662 +3 1661 4375 5824 +3 1504 4434 4482 +3 6991 6992 352 +3 4375 1661 2785 +3 2484 7197 2028 +3 1293 2030 1663 +3 1663 7029 7375 +3 2379 5924 4989 +3 5790 1355 3671 +3 5079 2157 3568 +3 147 2694 5466 +3 5405 5404 660 +3 1998 5831 554 +3 7057 5654 2694 +3 6979 6980 5610 +3 1547 6132 542 +3 2894 5356 2038 +3 2226 4614 2281 +3 5143 62 6032 +3 2038 28 6406 +3 1669 993 636 +3 1667 5147 2437 +3 1466 4147 1285 +3 5100 4632 3593 +3 82 4199 7168 +3 5147 1667 5301 +3 1668 5277 1998 +3 7040 6671 3453 +3 2783 1800 6520 +3 866 864 7372 +3 6909 5342 3895 +3 3950 7430 2372 +3 4697 6818 3012 +3 7438 7197 2484 +3 3446 5916 2618 +3 2096 854 5114 +3 7046 5288 6211 +3 1966 1441 2878 +3 1225 2842 2788 +3 2522 2094 1672 +3 1672 7046 1612 +3 5604 4681 7104 +3 6102 4274 1735 +3 1930 6654 263 +3 7336 2903 2769 +3 2150 3504 453 +3 1675 7050 1886 +3 1882 7050 1350 +3 1350 7050 2789 +3 2687 6621 3521 +3 4339 6621 2687 +3 2399 2194 2791 +3 7441 3939 5089 +3 1561 7524 356 +3 7241 7052 1808 +3 28 2038 5882 +3 28 7054 7253 +3 3007 4187 2792 +3 944 2995 6305 +3 2792 3609 3007 +3 6039 3299 190 +3 4095 7056 3589 +3 7056 7059 2215 +3 536 3970 3035 +3 5432 7465 2860 +3 6228 7059 7055 +3 2833 7089 4742 +3 3606 2555 2406 +3 1683 3962 1988 +3 5787 4866 5670 +3 5113 2108 4594 +3 2052 7063 2799 +3 718 4197 6034 +3 1990 7064 6888 +3 2045 4333 4037 +3 2891 7200 5888 +3 6888 7064 4728 +3 6539 160 5476 +3 7110 6361 6454 +3 1275 6902 6729 +3 1776 1687 1779 +3 1779 1687 1982 +3 5102 4904 1689 +3 1689 3781 5102 +3 2280 1113 2663 +3 1692 435 3802 +3 1023 1715 3974 +3 107 7069 5214 +3 3121 2563 5757 +3 6678 7069 3747 +3 3747 7069 2797 +3 4837 3192 5265 +3 6610 4798 241 +3 2557 6863 6301 +3 3002 2908 6521 +3 4080 7071 4868 +3 6594 7519 3643 +3 4868 7071 7072 +3 6259 7072 4034 +3 4034 7072 7070 +3 7073 4739 2554 +3 4739 7073 7411 +3 6154 7076 6841 +3 6033 6192 1469 +3 1930 263 5318 +3 3388 5281 4632 +3 6841 7076 4740 +3 4991 1527 2863 +3 2884 5610 7249 +3 1350 7505 1933 +3 2799 7064 3841 +3 3078 4525 7151 +3 1080 7079 68 +3 2536 7078 2801 +3 7119 1268 3026 +3 2427 3554 6861 +3 2683 1701 6293 +3 5116 5586 4441 +3 6960 5823 2009 +3 143 7081 2804 +3 3422 4956 1702 +3 4383 2605 7524 +3 7087 3451 4645 +3 5863 656 6329 +3 6540 7087 1268 +3 584 131 3720 +3 855 909 3247 +3 4742 3469 2833 +3 3568 376 5079 +3 4031 4032 3133 +3 3747 7093 7094 +3 7415 4961 849 +3 6668 5379 7242 +3 6236 7094 7090 +3 3080 3074 670 +3 355 7098 154 +3 154 7098 7099 +3 2999 6364 7003 +3 3572 1162 4974 +3 5687 7099 7097 +3 7265 7100 3489 +3 3489 7100 1986 +3 1069 3890 4186 +3 5727 7101 2511 +3 2511 7101 1983 +3 5792 3198 340 +3 4196 7105 7107 +3 7106 7107 4107 +3 1269 4431 3276 +3 2373 584 4993 +3 4107 4106 656 +3 1496 7107 7105 +3 7109 7095 1707 +3 7200 2891 474 +3 3890 1069 2172 +3 6672 4056 3890 +3 2345 2154 2800 +3 4691 2657 7510 +3 1709 4014 6069 +3 4354 7436 2633 +3 4887 5249 7114 +3 7153 4887 7114 +3 5653 2233 280 +3 1484 6241 6066 +3 5014 7118 6672 +3 6410 7120 3209 +3 3209 7120 7477 +3 7121 48 250 +3 48 7121 7451 +3 7333 7331 3041 +3 7126 1001 411 +3 1001 7126 7128 +3 1525 2735 208 +3 3608 5806 3023 +3 4880 5157 3234 +3 4660 4305 984 +3 3543 1607 2659 +3 4656 3988 1511 +3 7128 7125 1065 +3 1012 7131 1902 +3 5968 5969 1900 +3 3467 7132 7133 +3 2874 4186 3736 +3 2916 1821 2618 +3 3003 7133 4746 +3 4746 7133 7131 +3 546 7134 4350 +3 6616 7135 3317 +3 3317 7135 7137 +3 4713 4714 221 +3 121 7137 7134 +3 6909 6908 6523 +3 6929 6930 6027 +3 6428 7144 7482 +3 7150 787 908 +3 787 7150 1720 +3 7375 7373 1293 +3 4345 4344 786 +3 3195 7152 2806 +3 5744 2603 1315 +3 5568 712 7305 +3 1088 4598 1721 +3 3738 348 347 +3 1541 7150 908 +3 4038 5655 6047 +3 4382 1539 2542 +3 861 831 5722 +3 1988 2542 1683 +3 143 7158 7160 +3 5305 6306 3801 +3 6523 6258 6017 +3 6017 7157 7045 +3 2207 3019 7102 +3 4653 4655 3880 +3 6734 5986 4950 +3 5992 7162 7164 +3 6245 3046 5134 +3 487 7164 7161 +3 5942 7165 6833 +3 6833 491 923 +3 5285 2073 4294 +3 3415 3835 3017 +3 6641 7166 2107 +3 2844 7167 1408 +3 1408 7167 7499 +3 71 4382 4287 +3 7500 163 1724 +3 1724 1728 7500 +3 309 4617 2535 +3 2807 847 1895 +3 5527 3682 335 +3 3557 1941 2347 +3 5422 5225 3718 +3 1986 4531 1687 +3 1983 7100 4870 +3 4804 168 3277 +3 3142 3105 1947 +3 7411 7175 118 +3 118 7175 7424 +3 6767 3240 686 +3 686 1737 6767 +3 1737 2702 2191 +3 2889 5591 4263 +3 607 4308 643 +3 1926 4451 2882 +3 7181 1131 5585 +3 7181 7177 608 +3 356 5553 696 +3 7505 1350 1927 +3 7188 7183 198 +3 7183 7184 198 +3 2144 1866 7184 +3 2711 1927 4909 +3 1058 4294 1906 +3 2510 4531 1984 +3 6345 7188 2718 +3 5790 7189 1355 +3 2980 3661 3121 +3 1355 7189 7420 +3 6212 7191 532 +3 5774 7192 4750 +3 353 5158 2674 +3 2170 2261 2017 +3 3421 7465 5432 +3 4750 7192 7193 +3 5579 3156 1448 +3 6043 7193 7191 +3 2588 7194 7195 +3 2689 7305 712 +3 2321 2359 4066 +3 8 7195 7194 +3 2421 702 6744 +3 6564 6566 483 +3 1170 360 6015 +3 2010 3931 7037 +3 7196 7194 1746 +3 4705 3663 6643 +3 19 1889 286 +3 1898 252 27 +3 2137 6653 1838 +3 1747 3214 81 +3 1749 1768 1740 +3 5061 3386 6676 +3 7410 1869 2514 +3 2510 2857 7455 +3 2169 6166 512 +3 7235 2144 1752 +3 1014 6514 1943 +3 7523 2537 307 +3 3386 6181 6676 +3 7236 7206 2144 +3 1753 3110 7397 +3 3110 7207 7208 +3 3900 7208 4739 +3 3014 4650 6978 +3 7208 7206 2554 +3 1980 4772 5505 +3 2456 4066 6426 +3 7209 7057 1550 +3 5624 7210 6036 +3 1354 1991 6373 +3 1677 7210 7212 +3 6231 4121 416 +3 685 7212 2246 +3 4730 7215 7216 +3 4022 7216 3004 +3 3004 7216 7213 +3 1137 7217 1781 +3 2607 612 3870 +3 1756 6973 7416 +3 1757 7271 2817 +3 2168 1502 6283 +3 1838 5754 2137 +3 3281 7220 1940 +3 1940 5442 3281 +3 3144 4659 3444 +3 6348 7223 7471 +3 4718 4719 993 +3 6537 6538 6051 +3 1686 7230 7231 +3 7148 1946 6652 +3 6756 7231 5663 +3 6326 4216 7255 +3 5663 7231 7226 +3 6110 5780 3005 +3 7232 3359 2035 +3 5639 2377 4949 +3 5660 3821 5029 +3 5527 5052 3585 +3 2266 7234 5961 +3 126 5062 1081 +3 1740 1768 1752 +3 173 7073 2554 +3 6718 6720 3034 +3 6956 7238 492 +3 179 2815 492 +3 1926 7505 6446 +3 6674 4053 6670 +3 6766 5186 322 +3 3009 898 5572 +3 6153 7013 4163 +3 4205 7186 5572 +3 1778 7245 1774 +3 6579 4067 1907 +3 1774 1779 1778 +3 950 5998 1744 +3 1219 7266 7265 +3 2157 334 7159 +3 2150 2667 164 +3 1772 7263 1219 +3 2823 108 1773 +3 1830 7249 5610 +3 2846 258 7395 +3 7260 7250 1219 +3 1219 7250 7266 +3 3041 6500 3219 +3 7052 7054 1808 +3 6406 28 434 +3 6930 7254 6027 +3 2073 5285 7367 +3 468 6850 1533 +3 6841 4740 2881 +3 7118 7257 2937 +3 5751 5018 3086 +3 500 7258 7259 +3 7479 7259 1180 +3 1180 7259 7257 +3 6246 7260 3813 +3 5334 7261 1273 +3 7261 7263 1771 +3 2697 1745 3066 +3 1774 1776 1779 +3 388 4793 4021 +3 1219 7263 7260 +3 3489 1687 1776 +3 1194 4870 7100 +3 1194 7265 7266 +3 7306 7076 81 +3 7252 7250 144 +3 7457 3679 3729 +3 7265 1772 1219 +3 1273 7245 1782 +3 1780 6926 6927 +3 1755 1782 7268 +3 5073 5679 3140 +3 3066 1743 2697 +3 1781 2378 1137 +3 2817 6973 1757 +3 7504 1926 2882 +3 4508 6816 3452 +3 1784 1791 1264 +3 1905 7465 3258 +3 7149 4939 3334 +3 5653 7016 1787 +3 1787 1786 26 +3 2243 7274 221 +3 221 7274 2818 +3 4939 5143 6032 +3 150 4772 1979 +3 4262 4264 508 +3 7229 7277 4469 +3 2047 56 5765 +3 5344 56 2069 +3 765 5143 4939 +3 5676 5673 72 +3 5491 7278 7495 +3 1793 5857 2839 +3 1793 2822 5857 +3 27 2515 1878 +3 7286 2106 1645 +3 2106 1800 7285 +3 7326 7287 438 +3 438 7287 2823 +3 3876 3877 1200 +3 6673 7289 7292 +3 6820 6821 2435 +3 151 7288 3876 +3 1807 4821 875 +3 1807 1811 4821 +3 4470 2825 2002 +3 6156 7295 5382 +3 5382 2824 3355 +3 6995 7296 3189 +3 3189 7296 7297 +3 7296 1338 2133 +3 132 7421 7025 +3 5451 1744 4400 +3 2740 1039 3024 +3 70 7299 7153 +3 7153 7299 1815 +3 3607 6521 2908 +3 1814 4516 2816 +3 4142 166 2167 +3 616 4824 4935 +3 1650 1722 1119 +3 196 7399 594 +3 1925 1928 6482 +3 7434 5168 55 +3 3214 1823 1999 +3 4991 3554 4924 +3 3280 2724 3727 +3 1999 81 3214 +3 6033 7243 3795 +3 7306 150 1979 +3 7442 150 1999 +3 6530 6529 6948 +3 6748 7308 5335 +3 5335 7308 7309 +3 2939 7309 6998 +3 6998 7309 7307 +3 2830 5701 1948 +3 3993 4127 6884 +3 4601 2616 4932 +3 643 2353 1825 +3 2490 5684 177 +3 1825 42 643 +3 6429 7312 152 +3 7312 1989 6513 +3 5380 5381 590 +3 1925 6482 6722 +3 171 3387 1827 +3 1829 1841 171 +3 2767 2560 1468 +3 3790 7315 1861 +3 856 1894 7042 +3 6148 4341 3388 +3 5353 7256 7404 +3 7316 7317 1859 +3 2212 3664 5892 +3 7145 7317 2506 +3 2506 7317 7315 +3 1923 7499 7166 +3 2623 615 3636 +3 1366 7319 1312 +3 3254 6652 1946 +3 3954 7322 5040 +3 7323 438 1773 +3 6801 7326 197 +3 197 7326 5700 +3 5159 1884 6940 +3 6722 7328 1120 +3 7423 7329 3086 +3 3086 7329 7330 +3 905 2173 879 +3 7474 7330 486 +3 486 7330 7328 +3 7120 7331 6672 +3 6672 7331 4056 +3 3403 4724 3773 +3 7333 3041 3219 +3 5545 6683 312 +3 6271 7335 5936 +3 141 7337 1832 +3 1832 6557 4774 +3 7012 7337 7334 +3 48 7451 7448 +3 1833 1834 4028 +3 2542 1988 4382 +3 2542 7339 2837 +3 1835 2833 3469 +3 4476 7409 6404 +3 7342 262 7438 +3 6642 262 1836 +3 1837 2839 5857 +3 73 257 2838 +3 7182 7241 1808 +3 1338 4915 4824 +3 2573 2314 1891 +3 911 2071 7502 +3 3688 7463 4875 +3 3517 667 3522 +3 1981 5089 3939 +3 2396 4047 1261 +3 2553 6521 6520 +3 5046 7449 31 +3 7296 4915 1338 +3 4839 7390 529 +3 6958 4935 4834 +3 7178 2075 3217 +3 6398 7350 5148 +3 4475 3674 5161 +3 7351 7352 2775 +3 1840 6942 3230 +3 6593 7352 7350 +3 5401 7501 2866 +3 7354 7405 2849 +3 468 2847 5443 +3 1842 2148 2784 +3 6710 6711 5367 +3 5542 6173 3474 +3 204 4364 5811 +3 140 5503 5205 +3 140 7359 4817 +3 69 7123 3595 +3 1657 2865 904 +3 5234 7359 4867 +3 4867 7359 7356 +3 1844 4372 5885 +3 754 3186 4925 +3 1845 1848 2005 +3 1082 7361 4553 +3 769 6006 7436 +3 1846 7362 6261 +3 1306 7362 2841 +3 2841 4704 1306 +3 1467 2836 1221 +3 1849 5096 4944 +3 2483 7363 1857 +3 5587 5582 4363 +3 4673 5059 3363 +3 3290 4283 2845 +3 3772 4730 4218 +3 945 896 3683 +3 1855 7371 3625 +3 5598 4673 1655 +3 1850 7109 3625 +3 4520 7068 5067 +3 5067 7068 5237 +3 7372 7368 866 +3 5698 7373 5115 +3 5115 7373 7446 +3 7375 1293 1663 +3 7336 4038 6047 +3 1654 5475 5919 +3 833 5341 5552 +3 5341 834 7086 +3 1615 4702 4040 +3 4920 7377 3883 +3 3124 2551 7379 +3 1859 5894 7316 +3 1859 2020 5894 +3 4988 7444 7445 +3 1862 145 2058 +3 1862 7065 145 +3 1729 471 5106 +3 7383 1865 2434 +3 5983 3742 4733 +3 6944 7501 5401 +3 1408 7499 1922 +3 1863 7388 724 +3 7388 254 401 +3 5724 5997 5633 +3 1865 254 7388 +3 2407 1388 5350 +3 7424 7389 16 +3 16 7389 4269 +3 7391 1149 7238 +3 7393 7225 1620 +3 7225 7393 1914 +3 3921 1914 5604 +3 1328 7395 258 +3 7395 1978 2846 +3 2014 1980 5505 +3 4319 7397 3110 +3 1365 1344 6799 +3 7398 7419 129 +3 4160 7400 4691 +3 1356 5060 5203 +3 6518 7401 4037 +3 2751 7403 2848 +3 480 3938 2166 +3 2848 7403 1870 +3 6919 6918 1181 +3 2832 7355 7405 +3 2849 4615 5381 +3 5436 4205 4757 +3 2810 4971 1871 +3 6085 3993 4688 +3 1871 7403 1112 +3 6982 2879 4468 +3 3617 5103 5060 +3 4494 4365 5222 +3 1394 4924 1696 +3 7404 4857 7224 +3 5150 5144 500 +3 5602 3545 2418 +3 695 5517 2992 +3 7175 7073 1149 +3 1858 7166 7499 +3 4739 7411 3923 +3 1788 4488 2774 +3 1955 2851 2227 +3 926 5255 1874 +3 1874 7414 2662 +3 1310 1306 4704 +3 2850 2112 1310 +3 6279 1708 843 +3 7415 4106 1496 +3 3858 2204 3505 +3 4688 6884 863 +3 4106 6329 656 +3 5027 872 4921 +3 5807 7416 6973 +3 6743 7002 921 +3 1756 7416 1878 +3 27 1878 1898 +3 1753 7397 7419 +3 7188 7189 2718 +3 7432 1355 1553 +3 5018 7422 3086 +3 6355 6647 256 +3 7488 7423 16 +3 16 7423 7424 +3 6556 378 2153 +3 5056 5724 2478 +3 7389 7175 1149 +3 118 7424 7422 +3 685 2246 2301 +3 7045 6523 6017 +3 7430 7432 2300 +3 129 198 7398 +3 1355 7432 3671 +3 7006 3307 1143 +3 5673 7434 72 +3 72 7434 6277 +3 1751 2790 2003 +3 6643 4414 4660 +3 5219 627 484 +3 2795 2854 2484 +3 6233 7438 262 +3 4573 6499 5078 +3 7438 2854 7342 +3 1886 1937 1675 +3 2634 6855 2986 +3 1886 2852 5670 +3 3285 2525 2530 +3 7062 7443 145 +3 7444 4988 741 +3 844 3151 701 +3 441 7506 5620 +3 7506 441 4245 +3 2537 6463 307 +3 307 7441 1618 +3 7401 6518 5642 +3 4023 6630 106 +3 3584 7509 935 +3 3184 7509 3584 +3 1821 7510 2657 +3 2916 7510 1821 +3 7511 1320 2236 +3 1686 7511 3384 +3 158 7512 2153 +3 7512 158 6127 +3 3643 7513 6594 +3 5546 2998 3643 +3 4160 7514 4159 +3 7514 4160 7510 +3 7515 775 3606 +3 5642 6518 5662 +3 775 7516 3434 +3 7515 7516 775 +3 7517 6226 1320 +3 1686 7517 7511 +3 2010 7518 381 +3 7518 2010 7037 +3 7519 2121 1556 +3 4143 7519 2033 +3 7520 4857 7404 +3 4010 7520 7256 +3 2537 7523 5978 +3 6215 7521 96 +3 4025 7522 7202 +3 7522 4025 2982 +3 1119 1627 7521 +3 191 7507 2141 +3 7524 353 4383 +3 5553 7524 2605 +3 217 7525 1527 +3 377 217 5559 \ No newline at end of file diff --git a/src/Unittests/TestFiles/cube_poly_version_1_2.om b/src/Unittests/TestFiles/cube_poly_version_1_2.om new file mode 100644 index 00000000..fa583a99 Binary files /dev/null and b/src/Unittests/TestFiles/cube_poly_version_1_2.om differ diff --git a/src/Unittests/TestFiles/cube_poly_version_2_0.om b/src/Unittests/TestFiles/cube_poly_version_2_0.om new file mode 100644 index 00000000..ec32c759 Binary files /dev/null and b/src/Unittests/TestFiles/cube_poly_version_2_0.om differ diff --git a/src/Unittests/TestFiles/cube_tri_version_1_2.om b/src/Unittests/TestFiles/cube_tri_version_1_2.om new file mode 100644 index 00000000..126a2846 Binary files /dev/null and b/src/Unittests/TestFiles/cube_tri_version_1_2.om differ diff --git a/src/Unittests/TestFiles/cube_tri_version_2_0.om b/src/Unittests/TestFiles/cube_tri_version_2_0.om new file mode 100644 index 00000000..70ca37c3 Binary files /dev/null and b/src/Unittests/TestFiles/cube_tri_version_2_0.om differ diff --git a/src/Unittests/TestFiles/cube_tri_version_7_5.om b/src/Unittests/TestFiles/cube_tri_version_7_5.om new file mode 100644 index 00000000..78cead57 Binary files /dev/null and b/src/Unittests/TestFiles/cube_tri_version_7_5.om differ diff --git a/src/Unittests/TestFiles/sphere840.ply b/src/Unittests/TestFiles/sphere840.ply new file mode 100644 index 00000000..446dacc0 --- /dev/null +++ b/src/Unittests/TestFiles/sphere840.ply @@ -0,0 +1,1271 @@ +ply +format ascii 1.0 +element vertex 422 +property float x +property float y +property float z +element face 840 +property list uchar int vertex_indices +end_header +0 0 -127 +5 25 -125 +10 24 -125 +15 21 -125 +19 17 -125 +22 13 -125 +25 8 -125 +26 2 -125 +26 -3 -125 +25 -9 -125 +22 -14 -125 +19 -18 -125 +15 -22 -125 +10 -25 -125 +5 -26 -125 +0 -27 -125 +-6 -26 -125 +-11 -25 -125 +-16 -22 -125 +-20 -18 -125 +-23 -14 -125 +-26 -9 -125 +-27 -3 -125 +-27 2 -125 +-26 8 -125 +-23 13 -125 +-20 17 -125 +-16 21 -125 +-11 24 -125 +-6 25 -125 +-1 26 -125 +10 50 -117 +21 47 -117 +30 41 -117 +38 34 -117 +44 25 -117 +49 15 -117 +51 5 -117 +51 -6 -117 +49 -16 -117 +44 -26 -117 +38 -35 -117 +30 -42 -117 +21 -48 -117 +10 -51 -117 +0 -52 -117 +-11 -51 -117 +-22 -48 -117 +-31 -42 -117 +-39 -35 -117 +-45 -26 -117 +-50 -16 -117 +-52 -6 -117 +-52 5 -117 +-50 15 -117 +-45 25 -117 +-39 34 -117 +-31 41 -117 +-22 47 -117 +-11 50 -117 +-1 51 -117 +15 73 -103 +30 68 -103 +43 60 -103 +55 49 -103 +64 37 -103 +70 23 -103 +74 7 -103 +74 -8 -103 +70 -24 -103 +64 -38 -103 +55 -50 -103 +43 -61 -103 +30 -69 -103 +15 -74 -103 +0 -75 -103 +-16 -74 -103 +-31 -69 -103 +-44 -61 -103 +-56 -50 -103 +-65 -38 -103 +-71 -24 -103 +-75 -8 -103 +-75 7 -103 +-71 23 -103 +-65 37 -103 +-56 49 -103 +-44 60 -103 +-31 68 -103 +-16 73 -103 +-1 74 -103 +19 92 -85 +38 86 -85 +55 76 -85 +70 63 -85 +81 47 -85 +89 29 -85 +93 9 -85 +93 -10 -85 +89 -30 -85 +81 -48 -85 +70 -64 -85 +55 -77 -85 +38 -87 -85 +19 -93 -85 +0 -95 -85 +-20 -93 -85 +-39 -87 -85 +-56 -77 -85 +-71 -64 -85 +-82 -48 -85 +-90 -30 -85 +-94 -10 -85 +-94 9 -85 +-90 29 -85 +-82 47 -85 +-71 63 -85 +-56 76 -85 +-39 86 -85 +-20 92 -85 +-1 94 -85 +22 107 -64 +44 100 -64 +64 88 -64 +81 73 -64 +95 54 -64 +104 33 -64 +109 11 -64 +109 -12 -64 +104 -34 -64 +95 -55 -64 +81 -74 -64 +64 -89 -64 +44 -101 -64 +22 -108 -64 +0 -110 -64 +-23 -108 -64 +-45 -101 -64 +-65 -89 -64 +-82 -74 -64 +-96 -55 -64 +-105 -34 -64 +-110 -12 -64 +-110 11 -64 +-105 33 -64 +-96 54 -64 +-82 73 -64 +-65 88 -64 +-45 100 -64 +-23 107 -64 +-1 109 -64 +25 118 -40 +49 110 -40 +70 97 -40 +89 80 -40 +104 60 -40 +114 37 -40 +120 12 -40 +120 -13 -40 +114 -38 -40 +104 -61 -40 +89 -81 -40 +70 -98 -40 +49 -111 -40 +25 -119 -40 +0 -121 -40 +-26 -119 -40 +-50 -111 -40 +-71 -98 -40 +-90 -81 -40 +-105 -61 -40 +-115 -38 -40 +-121 -13 -40 +-121 12 -40 +-115 37 -40 +-105 60 -40 +-90 80 -40 +-71 97 -40 +-50 110 -40 +-26 118 -40 +-1 120 -40 +26 123 -14 +51 115 -14 +74 102 -14 +93 84 -14 +109 63 -14 +120 39 -14 +125 13 -14 +125 -14 -14 +120 -40 -14 +109 -64 -14 +93 -85 -14 +74 -103 -14 +51 -116 -14 +26 -124 -14 +0 -127 -14 +-27 -124 -14 +-52 -116 -14 +-75 -103 -14 +-94 -85 -14 +-110 -64 -14 +-121 -40 -14 +-126 -14 -14 +-126 13 -14 +-121 39 -14 +-110 63 -14 +-94 84 -14 +-75 102 -14 +-52 115 -14 +-27 123 -14 +-1 126 -14 +26 123 13 +51 115 13 +74 102 13 +93 84 13 +109 63 13 +120 39 13 +125 13 13 +125 -14 13 +120 -40 13 +109 -64 13 +93 -85 13 +74 -103 13 +51 -116 13 +26 -124 13 +0 -127 13 +-27 -124 13 +-52 -116 13 +-75 -103 13 +-94 -85 13 +-110 -64 13 +-121 -40 13 +-126 -14 13 +-126 13 13 +-121 39 13 +-110 63 13 +-94 84 13 +-75 102 13 +-52 115 13 +-27 123 13 +-1 126 13 +25 118 39 +49 110 39 +70 97 39 +89 80 39 +104 60 39 +114 37 39 +120 12 39 +120 -13 39 +114 -38 39 +104 -61 39 +89 -81 39 +70 -98 39 +49 -111 39 +25 -119 39 +0 -121 39 +-26 -119 39 +-50 -111 39 +-71 -98 39 +-90 -81 39 +-105 -61 39 +-115 -38 39 +-121 -13 39 +-121 12 39 +-115 37 39 +-105 60 39 +-90 80 39 +-71 97 39 +-50 110 39 +-26 118 39 +-1 120 39 +22 107 63 +44 100 63 +64 88 63 +81 73 63 +95 54 63 +104 33 63 +109 11 63 +109 -12 63 +104 -34 63 +95 -55 63 +81 -74 63 +64 -89 63 +44 -101 63 +22 -108 63 +0 -110 63 +-23 -108 63 +-45 -101 63 +-65 -89 63 +-82 -74 63 +-96 -55 63 +-105 -34 63 +-110 -12 63 +-110 11 63 +-105 33 63 +-96 54 63 +-82 73 63 +-65 88 63 +-45 100 63 +-23 107 63 +-1 109 63 +19 92 84 +38 86 84 +55 76 84 +70 63 84 +81 47 84 +89 29 84 +93 9 84 +93 -10 84 +89 -30 84 +81 -48 84 +70 -64 84 +55 -77 84 +38 -87 84 +19 -93 84 +0 -95 84 +-20 -93 84 +-39 -87 84 +-56 -77 84 +-71 -64 84 +-82 -48 84 +-90 -30 84 +-94 -10 84 +-94 9 84 +-90 29 84 +-82 47 84 +-71 63 84 +-56 76 84 +-39 86 84 +-20 92 84 +-1 94 84 +15 73 102 +30 68 102 +43 60 102 +55 49 102 +64 37 102 +70 23 102 +74 7 102 +74 -8 102 +70 -24 102 +64 -38 102 +55 -50 102 +43 -61 102 +30 -69 102 +15 -74 102 +0 -75 102 +-16 -74 102 +-31 -69 102 +-44 -61 102 +-56 -50 102 +-65 -38 102 +-71 -24 102 +-75 -8 102 +-75 7 102 +-71 23 102 +-65 37 102 +-56 49 102 +-44 60 102 +-31 68 102 +-16 73 102 +-1 74 102 +10 50 116 +21 47 116 +30 41 116 +38 34 116 +44 25 116 +49 15 116 +51 5 116 +51 -6 116 +49 -16 116 +44 -26 116 +38 -35 116 +30 -42 116 +21 -48 116 +10 -51 116 +0 -52 116 +-11 -51 116 +-22 -48 116 +-31 -42 116 +-39 -35 116 +-45 -26 116 +-50 -16 116 +-52 -6 116 +-52 5 116 +-50 15 116 +-45 25 116 +-39 34 116 +-31 41 116 +-22 47 116 +-11 50 116 +-1 51 116 +5 25 124 +10 24 124 +15 21 124 +19 17 124 +22 13 124 +25 8 124 +26 2 124 +26 -3 124 +25 -9 124 +22 -14 124 +19 -18 124 +15 -22 124 +10 -25 124 +5 -26 124 +0 -27 124 +-6 -26 124 +-11 -25 124 +-16 -22 124 +-20 -18 124 +-23 -14 124 +-26 -9 124 +-27 -3 124 +-27 2 124 +-26 8 124 +-23 13 124 +-20 17 124 +-16 21 124 +-11 24 124 +-6 25 124 +-1 26 124 +0 0 127 +3 0 1 2 +3 0 2 3 +3 0 3 4 +3 0 4 5 +3 0 5 6 +3 0 6 7 +3 0 7 8 +3 0 8 9 +3 0 9 10 +3 0 10 11 +3 0 11 12 +3 0 12 13 +3 0 13 14 +3 0 14 15 +3 0 15 16 +3 0 16 17 +3 0 17 18 +3 0 18 19 +3 0 19 20 +3 0 20 21 +3 0 21 22 +3 0 22 23 +3 0 23 24 +3 0 24 25 +3 0 25 26 +3 0 26 27 +3 0 27 28 +3 0 28 29 +3 0 29 30 +3 0 30 1 +3 1 32 2 +3 32 1 31 +3 2 33 3 +3 33 2 32 +3 3 34 4 +3 34 3 33 +3 4 35 5 +3 35 4 34 +3 5 36 6 +3 36 5 35 +3 6 37 7 +3 37 6 36 +3 7 38 8 +3 38 7 37 +3 8 39 9 +3 39 8 38 +3 9 40 10 +3 40 9 39 +3 10 41 11 +3 41 10 40 +3 11 42 12 +3 42 11 41 +3 12 43 13 +3 43 12 42 +3 13 44 14 +3 44 13 43 +3 14 45 15 +3 45 14 44 +3 15 46 16 +3 46 15 45 +3 16 47 17 +3 47 16 46 +3 17 48 18 +3 48 17 47 +3 18 49 19 +3 49 18 48 +3 19 50 20 +3 50 19 49 +3 20 51 21 +3 51 20 50 +3 21 52 22 +3 52 21 51 +3 22 53 23 +3 53 22 52 +3 23 54 24 +3 54 23 53 +3 24 55 25 +3 55 24 54 +3 25 56 26 +3 56 25 55 +3 26 57 27 +3 57 26 56 +3 27 58 28 +3 58 27 57 +3 28 59 29 +3 59 28 58 +3 29 60 30 +3 60 29 59 +3 30 31 1 +3 31 30 60 +3 31 62 32 +3 62 31 61 +3 32 63 33 +3 63 32 62 +3 33 64 34 +3 64 33 63 +3 34 65 35 +3 65 34 64 +3 35 66 36 +3 66 35 65 +3 36 67 37 +3 67 36 66 +3 37 68 38 +3 68 37 67 +3 38 69 39 +3 69 38 68 +3 39 70 40 +3 70 39 69 +3 40 71 41 +3 71 40 70 +3 41 72 42 +3 72 41 71 +3 42 73 43 +3 73 42 72 +3 43 74 44 +3 74 43 73 +3 44 75 45 +3 75 44 74 +3 45 76 46 +3 76 45 75 +3 46 77 47 +3 77 46 76 +3 47 78 48 +3 78 47 77 +3 48 79 49 +3 79 48 78 +3 49 80 50 +3 80 49 79 +3 50 81 51 +3 81 50 80 +3 51 82 52 +3 82 51 81 +3 52 83 53 +3 83 52 82 +3 53 84 54 +3 84 53 83 +3 54 85 55 +3 85 54 84 +3 55 86 56 +3 86 55 85 +3 56 87 57 +3 87 56 86 +3 57 88 58 +3 88 57 87 +3 58 89 59 +3 89 58 88 +3 59 90 60 +3 90 59 89 +3 60 61 31 +3 61 60 90 +3 61 92 62 +3 92 61 91 +3 62 93 63 +3 93 62 92 +3 63 94 64 +3 94 63 93 +3 64 95 65 +3 95 64 94 +3 65 96 66 +3 96 65 95 +3 66 97 67 +3 97 66 96 +3 67 98 68 +3 98 67 97 +3 68 99 69 +3 99 68 98 +3 69 100 70 +3 100 69 99 +3 70 101 71 +3 101 70 100 +3 71 102 72 +3 102 71 101 +3 72 103 73 +3 103 72 102 +3 73 104 74 +3 104 73 103 +3 74 105 75 +3 105 74 104 +3 75 106 76 +3 106 75 105 +3 76 107 77 +3 107 76 106 +3 77 108 78 +3 108 77 107 +3 78 109 79 +3 109 78 108 +3 79 110 80 +3 110 79 109 +3 80 111 81 +3 111 80 110 +3 81 112 82 +3 112 81 111 +3 82 113 83 +3 113 82 112 +3 83 114 84 +3 114 83 113 +3 84 115 85 +3 115 84 114 +3 85 116 86 +3 116 85 115 +3 86 117 87 +3 117 86 116 +3 87 118 88 +3 118 87 117 +3 88 119 89 +3 119 88 118 +3 89 120 90 +3 120 89 119 +3 90 91 61 +3 91 90 120 +3 91 122 92 +3 122 91 121 +3 92 123 93 +3 123 92 122 +3 93 124 94 +3 124 93 123 +3 94 125 95 +3 125 94 124 +3 95 126 96 +3 126 95 125 +3 96 127 97 +3 127 96 126 +3 97 128 98 +3 128 97 127 +3 98 129 99 +3 129 98 128 +3 99 130 100 +3 130 99 129 +3 100 131 101 +3 131 100 130 +3 101 132 102 +3 132 101 131 +3 102 133 103 +3 133 102 132 +3 103 134 104 +3 134 103 133 +3 104 135 105 +3 135 104 134 +3 105 136 106 +3 136 105 135 +3 106 137 107 +3 137 106 136 +3 107 138 108 +3 138 107 137 +3 108 139 109 +3 139 108 138 +3 109 140 110 +3 140 109 139 +3 110 141 111 +3 141 110 140 +3 111 142 112 +3 142 111 141 +3 112 143 113 +3 143 112 142 +3 113 144 114 +3 144 113 143 +3 114 145 115 +3 145 114 144 +3 115 146 116 +3 146 115 145 +3 116 147 117 +3 147 116 146 +3 117 148 118 +3 148 117 147 +3 118 149 119 +3 149 118 148 +3 119 150 120 +3 150 119 149 +3 120 121 91 +3 121 120 150 +3 121 152 122 +3 152 121 151 +3 122 153 123 +3 153 122 152 +3 123 154 124 +3 154 123 153 +3 124 155 125 +3 155 124 154 +3 125 156 126 +3 156 125 155 +3 126 157 127 +3 157 126 156 +3 127 158 128 +3 158 127 157 +3 128 159 129 +3 159 128 158 +3 129 160 130 +3 160 129 159 +3 130 161 131 +3 161 130 160 +3 131 162 132 +3 162 131 161 +3 132 163 133 +3 163 132 162 +3 133 164 134 +3 164 133 163 +3 134 165 135 +3 165 134 164 +3 135 166 136 +3 166 135 165 +3 136 167 137 +3 167 136 166 +3 137 168 138 +3 168 137 167 +3 138 169 139 +3 169 138 168 +3 139 170 140 +3 170 139 169 +3 140 171 141 +3 171 140 170 +3 141 172 142 +3 172 141 171 +3 142 173 143 +3 173 142 172 +3 143 174 144 +3 174 143 173 +3 144 175 145 +3 175 144 174 +3 145 176 146 +3 176 145 175 +3 146 177 147 +3 177 146 176 +3 147 178 148 +3 178 147 177 +3 148 179 149 +3 179 148 178 +3 149 180 150 +3 180 149 179 +3 150 151 121 +3 151 150 180 +3 151 182 152 +3 182 151 181 +3 152 183 153 +3 183 152 182 +3 153 184 154 +3 184 153 183 +3 154 185 155 +3 185 154 184 +3 155 186 156 +3 186 155 185 +3 156 187 157 +3 187 156 186 +3 157 188 158 +3 188 157 187 +3 158 189 159 +3 189 158 188 +3 159 190 160 +3 190 159 189 +3 160 191 161 +3 191 160 190 +3 161 192 162 +3 192 161 191 +3 162 193 163 +3 193 162 192 +3 163 194 164 +3 194 163 193 +3 164 195 165 +3 195 164 194 +3 165 196 166 +3 196 165 195 +3 166 197 167 +3 197 166 196 +3 167 198 168 +3 198 167 197 +3 168 199 169 +3 199 168 198 +3 169 200 170 +3 200 169 199 +3 170 201 171 +3 201 170 200 +3 171 202 172 +3 202 171 201 +3 172 203 173 +3 203 172 202 +3 173 204 174 +3 204 173 203 +3 174 205 175 +3 205 174 204 +3 175 206 176 +3 206 175 205 +3 176 207 177 +3 207 176 206 +3 177 208 178 +3 208 177 207 +3 178 209 179 +3 209 178 208 +3 179 210 180 +3 210 179 209 +3 180 181 151 +3 181 180 210 +3 181 212 182 +3 212 181 211 +3 182 213 183 +3 213 182 212 +3 183 214 184 +3 214 183 213 +3 184 215 185 +3 215 184 214 +3 185 216 186 +3 216 185 215 +3 186 217 187 +3 217 186 216 +3 187 218 188 +3 218 187 217 +3 188 219 189 +3 219 188 218 +3 189 220 190 +3 220 189 219 +3 190 221 191 +3 221 190 220 +3 191 222 192 +3 222 191 221 +3 192 223 193 +3 223 192 222 +3 193 224 194 +3 224 193 223 +3 194 225 195 +3 225 194 224 +3 195 226 196 +3 226 195 225 +3 196 227 197 +3 227 196 226 +3 197 228 198 +3 228 197 227 +3 198 229 199 +3 229 198 228 +3 199 230 200 +3 230 199 229 +3 200 231 201 +3 231 200 230 +3 201 232 202 +3 232 201 231 +3 202 233 203 +3 233 202 232 +3 203 234 204 +3 234 203 233 +3 204 235 205 +3 235 204 234 +3 205 236 206 +3 236 205 235 +3 206 237 207 +3 237 206 236 +3 207 238 208 +3 238 207 237 +3 208 239 209 +3 239 208 238 +3 209 240 210 +3 240 209 239 +3 210 211 181 +3 211 210 240 +3 211 242 212 +3 242 211 241 +3 212 243 213 +3 243 212 242 +3 213 244 214 +3 244 213 243 +3 214 245 215 +3 245 214 244 +3 215 246 216 +3 246 215 245 +3 216 247 217 +3 247 216 246 +3 217 248 218 +3 248 217 247 +3 218 249 219 +3 249 218 248 +3 219 250 220 +3 250 219 249 +3 220 251 221 +3 251 220 250 +3 221 252 222 +3 252 221 251 +3 222 253 223 +3 253 222 252 +3 223 254 224 +3 254 223 253 +3 224 255 225 +3 255 224 254 +3 225 256 226 +3 256 225 255 +3 226 257 227 +3 257 226 256 +3 227 258 228 +3 258 227 257 +3 228 259 229 +3 259 228 258 +3 229 260 230 +3 260 229 259 +3 230 261 231 +3 261 230 260 +3 231 262 232 +3 262 231 261 +3 232 263 233 +3 263 232 262 +3 233 264 234 +3 264 233 263 +3 234 265 235 +3 265 234 264 +3 235 266 236 +3 266 235 265 +3 236 267 237 +3 267 236 266 +3 237 268 238 +3 268 237 267 +3 238 269 239 +3 269 238 268 +3 239 270 240 +3 270 239 269 +3 240 241 211 +3 241 240 270 +3 241 272 242 +3 272 241 271 +3 242 273 243 +3 273 242 272 +3 243 274 244 +3 274 243 273 +3 244 275 245 +3 275 244 274 +3 245 276 246 +3 276 245 275 +3 246 277 247 +3 277 246 276 +3 247 278 248 +3 278 247 277 +3 248 279 249 +3 279 248 278 +3 249 280 250 +3 280 249 279 +3 250 281 251 +3 281 250 280 +3 251 282 252 +3 282 251 281 +3 252 283 253 +3 283 252 282 +3 253 284 254 +3 284 253 283 +3 254 285 255 +3 285 254 284 +3 255 286 256 +3 286 255 285 +3 256 287 257 +3 287 256 286 +3 257 288 258 +3 288 257 287 +3 258 289 259 +3 289 258 288 +3 259 290 260 +3 290 259 289 +3 260 291 261 +3 291 260 290 +3 261 292 262 +3 292 261 291 +3 262 293 263 +3 293 262 292 +3 263 294 264 +3 294 263 293 +3 264 295 265 +3 295 264 294 +3 265 296 266 +3 296 265 295 +3 266 297 267 +3 297 266 296 +3 267 298 268 +3 298 267 297 +3 268 299 269 +3 299 268 298 +3 269 300 270 +3 300 269 299 +3 270 271 241 +3 271 270 300 +3 271 302 272 +3 302 271 301 +3 272 303 273 +3 303 272 302 +3 273 304 274 +3 304 273 303 +3 274 305 275 +3 305 274 304 +3 275 306 276 +3 306 275 305 +3 276 307 277 +3 307 276 306 +3 277 308 278 +3 308 277 307 +3 278 309 279 +3 309 278 308 +3 279 310 280 +3 310 279 309 +3 280 311 281 +3 311 280 310 +3 281 312 282 +3 312 281 311 +3 282 313 283 +3 313 282 312 +3 283 314 284 +3 314 283 313 +3 284 315 285 +3 315 284 314 +3 285 316 286 +3 316 285 315 +3 286 317 287 +3 317 286 316 +3 287 318 288 +3 318 287 317 +3 288 319 289 +3 319 288 318 +3 289 320 290 +3 320 289 319 +3 290 321 291 +3 321 290 320 +3 291 322 292 +3 322 291 321 +3 292 323 293 +3 323 292 322 +3 293 324 294 +3 324 293 323 +3 294 325 295 +3 325 294 324 +3 295 326 296 +3 326 295 325 +3 296 327 297 +3 327 296 326 +3 297 328 298 +3 328 297 327 +3 298 329 299 +3 329 298 328 +3 299 330 300 +3 330 299 329 +3 300 301 271 +3 301 300 330 +3 301 332 302 +3 332 301 331 +3 302 333 303 +3 333 302 332 +3 303 334 304 +3 334 303 333 +3 304 335 305 +3 335 304 334 +3 305 336 306 +3 336 305 335 +3 306 337 307 +3 337 306 336 +3 307 338 308 +3 338 307 337 +3 308 339 309 +3 339 308 338 +3 309 340 310 +3 340 309 339 +3 310 341 311 +3 341 310 340 +3 311 342 312 +3 342 311 341 +3 312 343 313 +3 343 312 342 +3 313 344 314 +3 344 313 343 +3 314 345 315 +3 345 314 344 +3 315 346 316 +3 346 315 345 +3 316 347 317 +3 347 316 346 +3 317 348 318 +3 348 317 347 +3 318 349 319 +3 349 318 348 +3 319 350 320 +3 350 319 349 +3 320 351 321 +3 351 320 350 +3 321 352 322 +3 352 321 351 +3 322 353 323 +3 353 322 352 +3 323 354 324 +3 354 323 353 +3 324 355 325 +3 355 324 354 +3 325 356 326 +3 356 325 355 +3 326 357 327 +3 357 326 356 +3 327 358 328 +3 358 327 357 +3 328 359 329 +3 359 328 358 +3 329 360 330 +3 360 329 359 +3 330 331 301 +3 331 330 360 +3 331 362 332 +3 362 331 361 +3 332 363 333 +3 363 332 362 +3 333 364 334 +3 364 333 363 +3 334 365 335 +3 365 334 364 +3 335 366 336 +3 366 335 365 +3 336 367 337 +3 367 336 366 +3 337 368 338 +3 368 337 367 +3 338 369 339 +3 369 338 368 +3 339 370 340 +3 370 339 369 +3 340 371 341 +3 371 340 370 +3 341 372 342 +3 372 341 371 +3 342 373 343 +3 373 342 372 +3 343 374 344 +3 374 343 373 +3 344 375 345 +3 375 344 374 +3 345 376 346 +3 376 345 375 +3 346 377 347 +3 377 346 376 +3 347 378 348 +3 378 347 377 +3 348 379 349 +3 379 348 378 +3 349 380 350 +3 380 349 379 +3 350 381 351 +3 381 350 380 +3 351 382 352 +3 382 351 381 +3 352 383 353 +3 383 352 382 +3 353 384 354 +3 384 353 383 +3 354 385 355 +3 385 354 384 +3 355 386 356 +3 386 355 385 +3 356 387 357 +3 387 356 386 +3 357 388 358 +3 388 357 387 +3 358 389 359 +3 389 358 388 +3 359 390 360 +3 390 359 389 +3 360 361 331 +3 361 360 390 +3 361 392 362 +3 392 361 391 +3 362 393 363 +3 393 362 392 +3 363 394 364 +3 394 363 393 +3 364 395 365 +3 395 364 394 +3 365 396 366 +3 396 365 395 +3 366 397 367 +3 397 366 396 +3 367 398 368 +3 398 367 397 +3 368 399 369 +3 399 368 398 +3 369 400 370 +3 400 369 399 +3 370 401 371 +3 401 370 400 +3 371 402 372 +3 402 371 401 +3 372 403 373 +3 403 372 402 +3 373 404 374 +3 404 373 403 +3 374 405 375 +3 405 374 404 +3 375 406 376 +3 406 375 405 +3 376 407 377 +3 407 376 406 +3 377 408 378 +3 408 377 407 +3 378 409 379 +3 409 378 408 +3 379 410 380 +3 410 379 409 +3 380 411 381 +3 411 380 410 +3 381 412 382 +3 412 381 411 +3 382 413 383 +3 413 382 412 +3 383 414 384 +3 414 383 413 +3 384 415 385 +3 415 384 414 +3 385 416 386 +3 416 385 415 +3 386 417 387 +3 417 386 416 +3 387 418 388 +3 418 387 417 +3 388 419 389 +3 419 388 418 +3 389 420 390 +3 420 389 419 +3 390 391 361 +3 391 390 420 +3 391 421 392 +3 392 421 393 +3 393 421 394 +3 394 421 395 +3 395 421 396 +3 396 421 397 +3 397 421 398 +3 398 421 399 +3 399 421 400 +3 400 421 401 +3 401 421 402 +3 402 421 403 +3 403 421 404 +3 404 421 405 +3 405 421 406 +3 406 421 407 +3 407 421 408 +3 408 421 409 +3 409 421 410 +3 410 421 411 +3 411 421 412 +3 412 421 413 +3 413 421 414 +3 414 421 415 +3 415 421 416 +3 416 421 417 +3 417 421 418 +3 418 421 419 +3 419 421 420 +3 420 421 391 \ No newline at end of file diff --git a/src/Unittests/unittests_common.hh b/src/Unittests/unittests_common.hh index 5821cf64..04ca24b6 100644 --- a/src/Unittests/unittests_common.hh +++ b/src/Unittests/unittests_common.hh @@ -8,8 +8,16 @@ #include +#ifdef TEST_CUSTOM_TRAITS +#include +#elif defined(TEST_DOUBLE_TRAITS) +struct CustomTraits : public OpenMesh::DefaultTraitsDouble { +}; +#else struct CustomTraits : public OpenMesh::DefaultTraits { }; +#endif + typedef OpenMesh::TriMesh_ArrayKernelT Mesh; diff --git a/src/Unittests/unittests_common_customtraits.hh b/src/Unittests/unittests_common_customtraits.hh new file mode 100644 index 00000000..8bcdd918 --- /dev/null +++ b/src/Unittests/unittests_common_customtraits.hh @@ -0,0 +1,139 @@ +#ifndef UNITTESTS_COMMON_DUMMYTRAITS +#define UNITTESTS_COMMON_DUMMYTRAITS +#include +#include +#include + +namespace Custom { + +/// A Vector class with the absolute minimum of built-in methods to test the +/// interface expected from Vectors used in Traits +template class Vec { + public: + // Constructor with DIM components + Vec(float x) : data({ x }) {} + Vec(float x, float y) : data({ x, y }) {} + Vec(float x, float y, float z) : data({{ x, y, z }}) {} + Vec(float x, float y, float z, float w) : data({ x, y, z, w }) {} + + Vec() = default; + Vec(Vec const &) = default; + + float &operator[](int i) { return data[i]; } + float operator[](int i) const { return data[i]; } + + private: + std::array data; +}; + +template bool operator==(Vec const &lhs, Vec const &rhs) { + for (int i = 0; i < DIM; i++) + if (lhs[i] != rhs[i]) return false; + return true; +} + +template +Vec operator+(Vec const &lhs, Vec const &rhs) { + Vec result; + for (int i = 0; i < DIM; i++) + result[i] = lhs[i] + rhs[i]; + return result; +} + +template +Vec operator-(Vec const &lhs, Vec const &rhs) { + Vec result; + for (int i = 0; i < DIM; i++) + result[i] = lhs[i] - rhs[i]; + return result; +} + +template Vec operator*(Vec const &lhs, float rhs) { + Vec result; + for (int i = 0; i < DIM; i++) + result[i] = lhs[i] * rhs; + return result; +} + +template Vec operator*(float lhs, Vec const &rhs) { + return rhs * lhs; +} + +template Vec operator/(Vec const &lhs, float rhs) { + Vec result; + for (int i = 0; i < DIM; i++) + result[i] = lhs[i] / rhs; + return result; +} + +template Vec &operator+=(Vec &lhs, Vec const &rhs) { + return lhs = lhs + rhs; +} +template Vec &operator-=(Vec &lhs, Vec const &rhs) { + return lhs = lhs - rhs; +} +template Vec &operator*=(Vec &lhs, float rhs) { + return lhs = lhs * rhs; +} +template Vec &operator/=(Vec &lhs, float rhs) { + return lhs = lhs / rhs; +} + +template float norm(Vec const &v) { + float sum = 0.0f; + for (int i = 0; i < DIM; i++) + sum += v[i] * v[i]; + return std::sqrt(sum); +} + +template Vec &normalize(Vec &v) { return v /= norm(v); } +template Vec &vectorize(Vec &v, float val) { + for (int i = 0; i < DIM; i++) + v[i] = val; + return v; +} + +template Vec &minimize(Vec &v1, Vec const &v2) { + for (int i = 0; i < DIM; i++) + v1[i] = std::min(v1[i], v2[i]); + return v1; +} + +template Vec &maximize(Vec &v1, Vec const &v2) { + for (int i = 0; i < DIM; i++) + v1[i] = std::max(v1[i], v2[i]); + return v1; +} + +template float dot(Vec const &v1, Vec const &v2) { + float sum = 0.f; + for (int i = 0; i < DIM; i++) + sum += v1[i] * v2[i]; + return sum; +} + +inline Vec<3> cross(Vec<3> const &v1, Vec<3> const &v2) { + return {v1[1] * v2[2] - v1[2] * v2[1], // + v1[2] * v2[0] - v1[0] * v2[2], // + v1[0] * v2[1] - v1[1] * v2[0]}; +} +} + +namespace OpenMesh { +template struct vector_traits> { + using vector_type = Custom::Vec; + using value_type = float; + static const size_t size_ = DIM; + static size_t size() { return size_; } +}; +} + +struct CustomTraits : public OpenMesh::DefaultTraits { + typedef Custom::Vec<3> Point; + typedef Custom::Vec<3> Normal; + + typedef Custom::Vec<2> TexCoord2D; + typedef Custom::Vec<3> TexCoord3D; +}; + +#endif // UNITTESTS_COMMON_DUMMYTRAITS diff --git a/src/Unittests/unittests_convert_meshes.cc b/src/Unittests/unittests_convert_meshes.cc index 6cfd01bc..a86a78d9 100644 --- a/src/Unittests/unittests_convert_meshes.cc +++ b/src/Unittests/unittests_convert_meshes.cc @@ -285,19 +285,15 @@ TEST_F(OpenMeshConvertPolyMeshToTriangle, EdgePropertyCheckDouble) { // Check if it is ok. Mesh::EdgeIter v_it = p.edges_begin(); - if(p.is_boundary( (*v_it) )) EXPECT_EQ( p.property(doubleHandle,*v_it) , 0.0 ) << "Invalid double value for vertex 0"; ++v_it; - if(p.is_boundary( (*v_it) )) EXPECT_EQ( p.property(doubleHandle,*v_it) , 1.0 ) << "Invalid double value for vertex 1"; ++v_it; - if(p.is_boundary( (*v_it) )) EXPECT_EQ( p.property(doubleHandle,*v_it) , 2.0 ) << "Invalid double value for vertex 2"; ++v_it; - if(p.is_boundary( (*v_it) )) EXPECT_EQ( p.property(doubleHandle,*v_it) , 3.0 ) << "Invalid double value for vertex 3"; ++v_it; diff --git a/src/Unittests/unittests_decimater.cc b/src/Unittests/unittests_decimater.cc index d24439ca..2b7d2376 100644 --- a/src/Unittests/unittests_decimater.cc +++ b/src/Unittests/unittests_decimater.cc @@ -3,6 +3,7 @@ #include #include #include +#include namespace { @@ -49,7 +50,7 @@ TEST_F(OpenMeshDecimater, DecimateMesh) { decimaterDBG.initialize(); size_t removedVertices = 0; removedVertices = decimaterDBG.decimate_to(5000); - decimaterDBG.mesh().garbage_collection(); + decimaterDBG.mesh().garbage_collection(); EXPECT_EQ(2526u, removedVertices) << "The number of remove vertices is not correct!"; EXPECT_EQ(5000u, mesh_.n_vertices()) << "The number of vertices after decimation is not correct!"; @@ -72,7 +73,7 @@ TEST_F(OpenMeshDecimater, DecimateMeshToFaceVerticesLimit) { decimaterDBG.initialize(); size_t removedVertices = 0; removedVertices = decimaterDBG.decimate_to_faces(5000, 8000); - decimaterDBG.mesh().garbage_collection(); + decimaterDBG.mesh().garbage_collection(); EXPECT_EQ(2526u, removedVertices) << "The number of remove vertices is not correct!"; EXPECT_EQ(5000u, mesh_.n_vertices()) << "The number of vertices after decimation is not correct!"; @@ -95,7 +96,7 @@ TEST_F(OpenMeshDecimater, DecimateMeshToFaceFaceLimit) { decimaterDBG.initialize(); size_t removedVertices = 0; removedVertices = decimaterDBG.decimate_to_faces(4500, 9996); - decimaterDBG.mesh().garbage_collection(); + decimaterDBG.mesh().garbage_collection(); EXPECT_EQ(2526u, removedVertices) << "The number of remove vertices is not correct!"; EXPECT_EQ(5000u, mesh_.n_vertices()) << "The number of vertices after decimation is not correct!"; @@ -103,6 +104,34 @@ TEST_F(OpenMeshDecimater, DecimateMeshToFaceFaceLimit) { EXPECT_EQ(9996u, mesh_.n_faces()) << "The number of faces after decimation is not correct!"; } + +TEST_F(OpenMeshDecimater, DecimateMeshToVertexLimitWithLowNormalDeviation) { + + bool ok = OpenMesh::IO::read_mesh(mesh_, "cube1.off"); + + ASSERT_TRUE(ok); + + typedef OpenMesh::Decimater::DecimaterT< Mesh > Decimater; + typedef OpenMesh::Decimater::ModQuadricT< Mesh >::Handle HModQuadric; + typedef OpenMesh::Decimater::ModNormalDeviationT< Mesh >::Handle HModNormalDeviation; + + Decimater decimaterDBG(mesh_); + HModQuadric hModQuadricDBG; + decimaterDBG.add( hModQuadricDBG ); + HModNormalDeviation hModNormalDeviation; + decimaterDBG.add( hModNormalDeviation ); + decimaterDBG.module(hModNormalDeviation).set_normal_deviation(15.0); + decimaterDBG.initialize(); + size_t removedVertices = 0; + removedVertices = decimaterDBG.decimate_to(8); + decimaterDBG.mesh().garbage_collection(); + + EXPECT_EQ(6998u, removedVertices) << "The number of remove vertices is not correct!"; + EXPECT_EQ( 528u, mesh_.n_vertices()) << "The number of vertices after decimation is not correct!"; + EXPECT_EQ(1578u, mesh_.n_edges()) << "The number of edges after decimation is not correct!"; + EXPECT_EQ(1052u, mesh_.n_faces()) << "The number of faces after decimation is not correct!"; +} + TEST_F(OpenMeshDecimater, DecimateMeshExampleFromDoc) { bool ok = OpenMesh::IO::read_mesh(mesh_, "cube1.off"); @@ -121,7 +150,7 @@ TEST_F(OpenMeshDecimater, DecimateMeshExampleFromDoc) { decimaterDBG.initialize(); size_t removedVertices = 0; removedVertices = decimaterDBG.decimate_to_faces(4500, 9996); - decimaterDBG.mesh().garbage_collection(); + decimaterDBG.mesh().garbage_collection(); EXPECT_EQ(2526u, removedVertices) << "The number of remove vertices is not correct!"; EXPECT_EQ(5000u, mesh_.n_vertices()) << "The number of vertices after decimation is not correct!"; @@ -134,7 +163,7 @@ class UnittestObserver : public OpenMesh::Decimater::Observer size_t notifies_; size_t all_steps_; public: - UnittestObserver(size_t _steps) :Observer(_steps), notifies_(0), all_steps_(0) {} + explicit UnittestObserver(size_t _steps) :Observer(_steps), notifies_(0), all_steps_(0) {} void notify(size_t _step) { diff --git a/src/Unittests/unittests_eigen3_type.cc b/src/Unittests/unittests_eigen3_type.cc new file mode 100644 index 00000000..32be1046 --- /dev/null +++ b/src/Unittests/unittests_eigen3_type.cc @@ -0,0 +1,271 @@ + +#ifdef ENABLE_EIGEN3_TEST + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +struct EigenTraits : OpenMesh::DefaultTraits { + using Point = Eigen::Vector3d; + using Normal = Eigen::Vector3d; + + using TexCoord2D = Eigen::Vector2d; +}; + +using EigenTriMesh = OpenMesh::TriMesh_ArrayKernelT; + +namespace { + + +class OpenMeshEigenTest : public testing::Test { + + protected: + + // This function is called before each test is run + virtual void SetUp() { + + // Do some initial stuff with the member data here... + } + + // This function is called after all tests are through + virtual void TearDown() { + + + } + + EigenTriMesh mesh_; +}; + +TEST_F(OpenMeshEigenTest, Test_external_vectorize) { + + + EigenTriMesh::Normal normal; + + vectorize(normal,2); + + EXPECT_EQ(normal[0],2.0f ) << "Wrong x value"; + EXPECT_EQ(normal[1],2.0f ) << "Wrong y value"; + EXPECT_EQ(normal[2],2.0f ) << "Wrong z value"; + + +} + +TEST_F(OpenMeshEigenTest, Test_external_norm) { + + + EigenTriMesh::Normal normal(1,0,0); + + EigenTriMesh::Scalar result = norm(normal); + + EXPECT_EQ(result,1.0f ) << "Wrong norm"; + + normal = EigenTriMesh::Normal(2,0,0); + + result = norm(normal); + + EXPECT_EQ(result,2.0f ) << "Wrong norm"; +} + +TEST_F(OpenMeshEigenTest, Test_external_sqrnorm) { + + + EigenTriMesh::Normal normal(1,0,0); + + EigenTriMesh::Scalar result = sqrnorm(normal); + + EXPECT_EQ(result,1.0f ) << "Wrong norm"; + + normal = EigenTriMesh::Normal(2,0,0); + + result = sqrnorm(normal); + + EXPECT_EQ(result,4.0f ) << "Wrong norm"; +} + +TEST_F(OpenMeshEigenTest, Test_external_normalize) { + + + EigenTriMesh::Normal normal(2,0,0); + + normalize(normal); + + EXPECT_EQ(norm(normal),1.0f ) << "Wrong norm after normalization"; + + normal = EigenTriMesh::Normal(2,6,9); + + normalize(normal); + + EXPECT_EQ(norm(normal),1.0f ) << "Wrong norm after normalization"; + +} + +TEST_F(OpenMeshEigenTest, Test_external_cross_Product) { + + + EigenTriMesh::Normal normal1(1,0,0); + EigenTriMesh::Normal normal2(1,1,0); + + EigenTriMesh::Normal result = cross(normal1,normal2); + + EXPECT_EQ(result[0],0.0f ) << "Wrong result x direction"; + EXPECT_EQ(result[1],0.0f ) << "Wrong result y direction"; + EXPECT_EQ(result[2],1.0f ) << "Wrong result z direction"; +} + +TEST_F(OpenMeshEigenTest, Test_external_dot_Product) { + + + EigenTriMesh::Normal normal1(1,0,0); + EigenTriMesh::Normal normal2(1,1,0); + EigenTriMesh::Normal normal3(1,1,1); + EigenTriMesh::Normal normal4(2,4,6); + + EigenTriMesh::Scalar result = dot(normal1,normal2); + EigenTriMesh::Scalar result1 = dot(normal3,normal4); + + EXPECT_EQ(result,1.0f ) << "Wrong dot product"; + EXPECT_EQ(result1,12.0f ) << "Wrong dot product"; + +} + + +TEST_F(OpenMeshEigenTest, Test_Basic_setup) { + + // Add some vertices + EigenTriMesh::VertexHandle vhandle[4]; + + vhandle[0] = mesh_.add_vertex(EigenTriMesh::Point(0, 0, 0)); + vhandle[1] = mesh_.add_vertex(EigenTriMesh::Point(0, 1, 0)); + vhandle[2] = mesh_.add_vertex(EigenTriMesh::Point(1, 1, 0)); + vhandle[3] = mesh_.add_vertex(EigenTriMesh::Point(1, 0, 0)); + + // Add two faces + std::vector face_vhandles; + + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[0]); + + mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[0]); + face_vhandles.push_back(vhandle[3]); + mesh_.add_face(face_vhandles); + + + EXPECT_EQ(mesh_.n_faces(),2u) << "Wrong number of faces"; + +} + +TEST_F(OpenMeshEigenTest, test_normal_computation) { + + // Add some vertices + EigenTriMesh::VertexHandle vhandle[4]; + + mesh_.request_vertex_normals(); + mesh_.request_face_normals(); + + vhandle[0] = mesh_.add_vertex(EigenTriMesh::Point(0, 0, 0)); + vhandle[1] = mesh_.add_vertex(EigenTriMesh::Point(0, 1, 0)); + vhandle[2] = mesh_.add_vertex(EigenTriMesh::Point(1, 1, 0)); + vhandle[3] = mesh_.add_vertex(EigenTriMesh::Point(1, 0, 0)); + + // Add two faces + std::vector face_vhandles; + + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[0]); + + EigenTriMesh::FaceHandle face1 = mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[0]); + face_vhandles.push_back(vhandle[3]); + EigenTriMesh::FaceHandle face2 = mesh_.add_face(face_vhandles); + + mesh_.update_face_normals(); + + + EXPECT_EQ(mesh_.n_faces(),2u) << "Wrong number of faces"; + + EigenTriMesh::Normal normal = mesh_.normal(face1); + + EXPECT_EQ(normal[0],0.0f ) << "Wrong normal x direction"; + EXPECT_EQ(normal[1],0.0f ) << "Wrong normal y direction"; + EXPECT_EQ(normal[2],1.0f ) << "Wrong normal z direction"; + + normal = mesh_.normal(face2); + + EXPECT_EQ(normal[0],0.0f ) << "Wrong normal x direction"; + EXPECT_EQ(normal[1],0.0f ) << "Wrong normal y direction"; + EXPECT_EQ(normal[2],1.0f ) << "Wrong normal z direction"; + +} + +/* Just load a simple mesh file in obj format and count whether +* the right number of entities has been loaded. Afterwards recompute +* normals +*/ +TEST_F(OpenMeshEigenTest, LoadSimpleOFFFile) { + + mesh_.clear(); + + bool ok = OpenMesh::IO::read_mesh(mesh_, "cube1.off"); + + EXPECT_TRUE(ok); + + EXPECT_EQ(7526u , mesh_.n_vertices()) << "The number of loaded vertices is not correct!"; + EXPECT_EQ(22572u, mesh_.n_edges()) << "The number of loaded edges is not correct!"; + EXPECT_EQ(15048u, mesh_.n_faces()) << "The number of loaded faces is not correct!"; + + mesh_.update_normals(); +} + +// Test decimation with Eigen as vector type +TEST_F(OpenMeshEigenTest, Decimater) { + mesh_.clear(); + + bool ok = OpenMesh::IO::read_mesh(mesh_, "cube1.off"); + + EXPECT_TRUE(ok); + + EXPECT_EQ(7526u , mesh_.n_vertices()) << "The number of loaded vertices is not correct!"; + EXPECT_EQ(22572u, mesh_.n_edges()) << "The number of loaded edges is not correct!"; + EXPECT_EQ(15048u, mesh_.n_faces()) << "The number of loaded faces is not correct!"; + + mesh_.update_normals(); + + OpenMesh::Decimater::DecimaterT decimater(mesh_); + OpenMesh::Decimater::ModQuadricT::Handle hModQuadric; // use a quadric module + OpenMesh::Decimater::ModNormalDeviationT::Handle hModNormalDeviation; // also use normal deviation module as binary check + decimater.add(hModQuadric); + decimater.add(hModNormalDeviation); + decimater.module(hModQuadric).unset_max_err(); + decimater.module(hModNormalDeviation).set_normal_deviation(15); + decimater.initialize(); + size_t removedVertices = decimater.decimate_to(8); + mesh_.garbage_collection(); + + EXPECT_EQ(6998u, removedVertices) << "The number of remove vertices is not correct!"; + EXPECT_EQ( 528u, mesh_.n_vertices()) << "The number of vertices after decimation is not correct!"; + EXPECT_EQ(1578u, mesh_.n_edges()) << "The number of edges after decimation is not correct!"; + EXPECT_EQ(1052u, mesh_.n_faces()) << "The number of faces after decimation is not correct!"; +} + +} + +#endif diff --git a/src/Unittests/unittests_mc_decimater.cc b/src/Unittests/unittests_mc_decimater.cc index 3a206c24..7df7a599 100644 --- a/src/Unittests/unittests_mc_decimater.cc +++ b/src/Unittests/unittests_mc_decimater.cc @@ -43,7 +43,6 @@ TEST_F(OpenMeshMultipleChoiceDecimater, DecimateMesh) { typedef OpenMesh::Decimater::McDecimaterT< Mesh > Decimater; typedef OpenMesh::Decimater::ModQuadricT< Mesh >::Handle HModQuadric; - typedef OpenMesh::Decimater::ModNormalFlippingT< Mesh >::Handle HModNormal; Decimater decimaterDBG(mesh_); HModQuadric hModQuadricDBG; @@ -67,7 +66,6 @@ TEST_F(OpenMeshMultipleChoiceDecimater, DecimateMeshToFaceVerticesLimit) { typedef OpenMesh::Decimater::McDecimaterT< Mesh > Decimater; typedef OpenMesh::Decimater::ModQuadricT< Mesh >::Handle HModQuadric; - typedef OpenMesh::Decimater::ModNormalFlippingT< Mesh >::Handle HModNormal; Decimater decimaterDBG(mesh_); HModQuadric hModQuadricDBG; @@ -91,7 +89,6 @@ TEST_F(OpenMeshMultipleChoiceDecimater, DecimateMeshToFaceFaceLimit) { typedef OpenMesh::Decimater::McDecimaterT< Mesh > Decimater; typedef OpenMesh::Decimater::ModQuadricT< Mesh >::Handle HModQuadric; - typedef OpenMesh::Decimater::ModNormalFlippingT< Mesh >::Handle HModNormal; Decimater decimaterDBG(mesh_); HModQuadric hModQuadricDBG; @@ -112,7 +109,7 @@ class UnittestObserver : public OpenMesh::Decimater::Observer size_t notifies_; size_t all_steps_; public: - UnittestObserver(size_t _steps) :Observer(_steps), notifies_(0), all_steps_(0) {} + explicit UnittestObserver(size_t _steps) :Observer(_steps), notifies_(0), all_steps_(0) {} void notify(size_t _step) { diff --git a/src/Unittests/unittests_mesh_type.cc b/src/Unittests/unittests_mesh_type.cc new file mode 100644 index 00000000..309567d0 --- /dev/null +++ b/src/Unittests/unittests_mesh_type.cc @@ -0,0 +1,67 @@ +#include + +#include + + +namespace { + + +class OpenMeshTypeTest_Poly : public OpenMeshBasePoly { + + protected: + + // This function is called before each test is run + virtual void SetUp() { + + // Do some initial stuff with the member data here... + } + + // This function is called after all tests are through + virtual void TearDown() { + + // Do some final stuff with the member data here... + } +}; + +class OpenMeshTypeTest_Triangle : public OpenMeshBase { + + protected: + + // This function is called before each test is run + virtual void SetUp() { + + // Do some initial stuff with the member data here... + } + + // This function is called after all tests are through + virtual void TearDown() { + + // Do some final stuff with the member data here... + } + +}; + + +/* + * ==================================================================== + * Define tests below + * ==================================================================== + */ + +TEST_F(OpenMeshTypeTest_Triangle, testTypeFunctions) { + + + EXPECT_TRUE(mesh_.is_trimesh()) << "Type Error!"; + EXPECT_FALSE(mesh_.is_polymesh()) << "Type Error!"; +} + + +TEST_F(OpenMeshTypeTest_Poly, testTypeFunctions) { + + + EXPECT_FALSE(mesh_.is_trimesh()) << "Type Error!"; + EXPECT_TRUE(mesh_.is_polymesh()) << "Type Error!"; +} + + +} diff --git a/src/Unittests/unittests_mixed_decimater.cc b/src/Unittests/unittests_mixed_decimater.cc index cd892e44..62422bb2 100644 --- a/src/Unittests/unittests_mixed_decimater.cc +++ b/src/Unittests/unittests_mixed_decimater.cc @@ -43,7 +43,6 @@ TEST_F(OpenMeshMixedDecimater, DecimateMesh80PercentMc) { typedef OpenMesh::Decimater::MixedDecimaterT< Mesh > Decimater; typedef OpenMesh::Decimater::ModQuadricT< Mesh >::Handle HModQuadric; - typedef OpenMesh::Decimater::ModNormalFlippingT< Mesh >::Handle HModNormal; Decimater decimaterDBG(mesh_); HModQuadric hModQuadricDBG; @@ -67,7 +66,6 @@ TEST_F(OpenMeshMixedDecimater, DecimateMeshToFaceVerticesLimit) { typedef OpenMesh::Decimater::MixedDecimaterT< Mesh > Decimater; typedef OpenMesh::Decimater::ModQuadricT< Mesh >::Handle HModQuadric; - typedef OpenMesh::Decimater::ModNormalFlippingT< Mesh >::Handle HModNormal; Decimater decimaterDBG(mesh_); HModQuadric hModQuadricDBG; @@ -91,7 +89,6 @@ TEST_F(OpenMeshMixedDecimater, DecimateMeshToFaceFaceLimit) { typedef OpenMesh::Decimater::MixedDecimaterT< Mesh > Decimater; typedef OpenMesh::Decimater::ModQuadricT< Mesh >::Handle HModQuadric; - typedef OpenMesh::Decimater::ModNormalFlippingT< Mesh >::Handle HModNormal; Decimater decimaterDBG(mesh_); HModQuadric hModQuadricDBG; @@ -112,7 +109,7 @@ class UnittestObserver : public OpenMesh::Decimater::Observer size_t notifies_; size_t all_steps_; public: - UnittestObserver(size_t _steps) :Observer(_steps), notifies_(0), all_steps_(0) {} + explicit UnittestObserver(size_t _steps) :Observer(_steps), notifies_(0), all_steps_(0) {} void notify(size_t _step) { diff --git a/src/Unittests/unittests_normal_calculations.cc b/src/Unittests/unittests_normal_calculations.cc index 07342a67..30d350f0 100644 --- a/src/Unittests/unittests_normal_calculations.cc +++ b/src/Unittests/unittests_normal_calculations.cc @@ -247,7 +247,7 @@ TEST_F(OpenMeshNormals, NormalCalculations_calc_vertex_normal_fast) { mesh_.request_face_normals(); - OpenMesh::Vec3f normal; + Mesh::Normal normal; mesh_.calc_vertex_normal_fast(vhandle[2],normal); @@ -304,7 +304,7 @@ TEST_F(OpenMeshNormals, NormalCalculations_calc_vertex_normal_correct) { mesh_.request_halfedge_normals(); mesh_.request_face_normals(); - OpenMesh::Vec3f normal; + Mesh::Normal normal; mesh_.calc_vertex_normal_correct(vhandle[2],normal); @@ -361,7 +361,7 @@ TEST_F(OpenMeshNormals, NormalCalculations_calc_vertex_normal_loop) { mesh_.request_halfedge_normals(); mesh_.request_face_normals(); - OpenMesh::Vec3f normal; + Mesh::Normal normal; mesh_.calc_vertex_normal_loop(vhandle[2],normal); diff --git a/src/Unittests/unittests_polymesh_collapse.cc b/src/Unittests/unittests_polymesh_collapse.cc new file mode 100644 index 00000000..594dd1b6 --- /dev/null +++ b/src/Unittests/unittests_polymesh_collapse.cc @@ -0,0 +1,70 @@ +#include +#include + +#include + +namespace { + +class OpenMeshCollapsePoly : public OpenMeshBasePoly { + + protected: + + // This function is called before each test is run + virtual void SetUp() { + } + + // This function is called after all tests are through + virtual void TearDown() { + + // Do some final stuff with the member data here... + } + + // Member already defined in OpenMeshBase + //Mesh mesh_; +}; + +/* + * ==================================================================== + * Define tests below + * ==================================================================== + */ + + + + +/* + * This code tests is_collapse_ok on a double sided triangle. The + * test mesh comprises three vertices, that are connected to form two + * triangles of opposite orientation. All halfedges should be non collapsable. + */ +TEST_F(OpenMeshCollapsePoly, CheckCollapseOkDoublesidedTriangle) { + + mesh_.clear(); + + Mesh::VertexHandle vh0 = mesh_.add_vertex(Mesh::Point(0,0,0)); + Mesh::VertexHandle vh1 = mesh_.add_vertex(Mesh::Point(1,0,0)); + Mesh::VertexHandle vh2 = mesh_.add_vertex(Mesh::Point(1,1,0)); + mesh_.add_face(vh0, vh1, vh2); + mesh_.add_face(vh0, vh2, vh1); + + + + mesh_.request_vertex_status(); + mesh_.request_face_status(); + mesh_.request_edge_status(); + + int collapsable = 0; + + for ( const auto hh : mesh_.all_halfedges() ) + { + if (mesh_.is_collapse_ok(hh) ) + collapsable++; + } + + + EXPECT_EQ(collapsable,0) << "No collapse should be ok when we have only a double sided Triangle"; +} + + + +} diff --git a/src/Unittests/unittests_property.cc b/src/Unittests/unittests_property.cc index 0a0a0a14..f9b0b45c 100644 --- a/src/Unittests/unittests_property.cc +++ b/src/Unittests/unittests_property.cc @@ -746,5 +746,111 @@ TEST_F(OpenMeshProperties, PropertyIterators ) { } +TEST_F(OpenMeshProperties, MeshAssignment ) { + + mesh_.clear(); + mesh_.add_vertex(Mesh::Point()); + + auto copy = mesh_; + + copy.request_vertex_status(); + copy.request_vertex_normals(); + copy.request_vertex_colors(); + copy.request_vertex_texcoords1D(); + copy.request_vertex_texcoords2D(); + copy.request_vertex_texcoords3D(); + copy.request_halfedge_status(); + copy.request_halfedge_texcoords1D(); + copy.request_halfedge_texcoords2D(); + copy.request_halfedge_texcoords3D(); + copy.request_edge_status(); + copy.request_edge_colors(); + copy.request_halfedge_normals(); + copy.request_halfedge_colors(); + copy.request_face_status(); + copy.request_face_normals(); + copy.request_face_colors(); + copy.request_face_texture_index(); + + EXPECT_TRUE(copy.has_vertex_status()); + EXPECT_TRUE(copy.has_vertex_normals()); + EXPECT_TRUE(copy.has_vertex_colors()); + EXPECT_TRUE(copy.has_vertex_texcoords1D()); + EXPECT_TRUE(copy.has_vertex_texcoords2D()); + EXPECT_TRUE(copy.has_vertex_texcoords3D()); + EXPECT_TRUE(copy.has_halfedge_status()); + EXPECT_TRUE(copy.has_halfedge_texcoords1D()); + EXPECT_TRUE(copy.has_halfedge_texcoords2D()); + EXPECT_TRUE(copy.has_halfedge_texcoords3D()); + EXPECT_TRUE(copy.has_edge_status()); + EXPECT_TRUE(copy.has_edge_colors()); + EXPECT_TRUE(copy.has_halfedge_normals()); + EXPECT_TRUE(copy.has_halfedge_colors()); + EXPECT_TRUE(copy.has_face_status()); + EXPECT_TRUE(copy.has_face_normals()); + EXPECT_TRUE(copy.has_face_colors()); + EXPECT_TRUE(copy.has_face_texture_index()); + + copy.assign(mesh_, true); + + EXPECT_FALSE(copy.has_vertex_status()); + EXPECT_FALSE(copy.has_vertex_normals()); + EXPECT_FALSE(copy.has_vertex_colors()); + EXPECT_FALSE(copy.has_vertex_texcoords1D()); + EXPECT_FALSE(copy.has_vertex_texcoords2D()); + EXPECT_FALSE(copy.has_vertex_texcoords3D()); + EXPECT_FALSE(copy.has_halfedge_status()); + EXPECT_FALSE(copy.has_halfedge_texcoords1D()); + EXPECT_FALSE(copy.has_halfedge_texcoords2D()); + EXPECT_FALSE(copy.has_halfedge_texcoords3D()); + EXPECT_FALSE(copy.has_edge_status()); + EXPECT_FALSE(copy.has_edge_colors()); + EXPECT_FALSE(copy.has_halfedge_normals()); + EXPECT_FALSE(copy.has_halfedge_colors()); + EXPECT_FALSE(copy.has_face_status()); + EXPECT_FALSE(copy.has_face_normals()); + EXPECT_FALSE(copy.has_face_colors()); + EXPECT_FALSE(copy.has_face_texture_index()); + + copy.request_vertex_status(); + copy.request_vertex_normals(); + copy.request_vertex_colors(); + copy.request_vertex_texcoords1D(); + copy.request_vertex_texcoords2D(); + copy.request_vertex_texcoords3D(); + copy.request_halfedge_status(); + copy.request_halfedge_texcoords1D(); + copy.request_halfedge_texcoords2D(); + copy.request_halfedge_texcoords3D(); + copy.request_edge_status(); + copy.request_edge_colors(); + copy.request_halfedge_normals(); + copy.request_halfedge_colors(); + copy.request_face_status(); + copy.request_face_normals(); + copy.request_face_colors(); + copy.request_face_texture_index(); + + EXPECT_TRUE(copy.has_vertex_status()) << "Mesh has no vertex status even though they have been requested"; + EXPECT_TRUE(copy.has_vertex_normals()) << "Mesh has no vertex normals even though they have been requested"; + EXPECT_TRUE(copy.has_vertex_colors()) << "Mesh has no vertex colors even though they have been requested"; + EXPECT_TRUE(copy.has_vertex_texcoords1D()) << "Mesh has no vertex texcoord1D even though they have been requested"; + EXPECT_TRUE(copy.has_vertex_texcoords2D()) << "Mesh has no vertex texcoord2D even though they have been requested"; + EXPECT_TRUE(copy.has_vertex_texcoords3D()) << "Mesh has no vertex texcoord3D even though they have been requested"; + EXPECT_TRUE(copy.has_halfedge_status()) << "Mesh has no halfedge status even though they have been requested"; + EXPECT_TRUE(copy.has_halfedge_texcoords1D()) << "Mesh has no halfedge texcoords1D even though they have been requested"; + EXPECT_TRUE(copy.has_halfedge_texcoords2D()) << "Mesh has no halfedge texcoords2D even though they have been requested"; + EXPECT_TRUE(copy.has_halfedge_texcoords3D()) << "Mesh has no halfedge texcoords3D even though they have been requested"; + EXPECT_TRUE(copy.has_edge_status()) << "Mesh has no edge status even though they have been requested"; + EXPECT_TRUE(copy.has_edge_colors()) << "Mesh has no edge colors even though they have been requested"; + EXPECT_TRUE(copy.has_halfedge_normals()) << "Mesh has no halfedge normals even though they have been requested"; + EXPECT_TRUE(copy.has_halfedge_colors()) << "Mesh has no halfedge colors even though they have been requested"; + EXPECT_TRUE(copy.has_face_status()) << "Mesh has no face status even though they have been requested"; + EXPECT_TRUE(copy.has_face_normals()) << "Mesh has no face normals even though they have been requested"; + EXPECT_TRUE(copy.has_face_colors()) << "Mesh has no face colors even though they have been requested"; + EXPECT_TRUE(copy.has_face_texture_index()) << "Mesh has no face texture index even though they have been requested"; + +} + } diff --git a/src/Unittests/unittests_propertymanager.cc b/src/Unittests/unittests_propertymanager.cc index 3fd7b646..87c92b95 100644 --- a/src/Unittests/unittests_propertymanager.cc +++ b/src/Unittests/unittests_propertymanager.cc @@ -4,6 +4,15 @@ #include +//#define ENABLE_PROPERTY_TIMING_OUTPUT +#ifdef ENABLE_PROPERTY_TIMING_OUTPUT +#define N_VERTICES_TIMING 1000000 +#define TIMING_OUTPUT(X) X +#else +#define N_VERTICES_TIMING 10 +#define TIMING_OUTPUT(X) +#endif + namespace { class OpenMeshPropertyManager : public OpenMeshBase { @@ -62,7 +71,7 @@ TEST_F(OpenMeshPropertyManager, set_range_bool) { { OpenMesh::PropertyManager< - OpenMesh::VPropHandleT, Mesh> pm_v_bool(mesh_, "pm_v_bool"); + OpenMesh::VPropHandleT> pm_v_bool(mesh_, "pm_v_bool"); pm_v_bool.set_range(mesh_.vertices_begin(), mesh_.vertices_end(), false); for (int i = 0; i < 4; ++i) ASSERT_FALSE(pm_v_bool[vhandle[i]]); @@ -71,7 +80,7 @@ TEST_F(OpenMeshPropertyManager, set_range_bool) { ASSERT_TRUE(pm_v_bool[vhandle[i]]); OpenMesh::PropertyManager< - OpenMesh::EPropHandleT, Mesh> pm_e_bool(mesh_, "pm_e_bool"); + OpenMesh::EPropHandleT> pm_e_bool(mesh_, "pm_e_bool"); pm_e_bool.set_range(mesh_.edges_begin(), mesh_.edges_end(), false); for (Mesh::EdgeIter e_it = mesh_.edges_begin(), f_end = mesh_.edges_end(); e_it != f_end; ++e_it) @@ -82,7 +91,7 @@ TEST_F(OpenMeshPropertyManager, set_range_bool) { ASSERT_TRUE(pm_e_bool[*e_it]); OpenMesh::PropertyManager< - OpenMesh::FPropHandleT, Mesh> pm_f_bool(mesh_, "pm_f_bool"); + OpenMesh::FPropHandleT> pm_f_bool(mesh_, "pm_f_bool"); pm_f_bool.set_range(mesh_.faces_begin(), mesh_.faces_end(), false); for (Mesh::FaceIter f_it = mesh_.faces_begin(), f_end = mesh_.faces_end(); f_it != f_end; ++f_it) @@ -93,13 +102,12 @@ TEST_F(OpenMeshPropertyManager, set_range_bool) { ASSERT_TRUE(pm_f_bool[*f_it]); } -#if (defined(_MSC_VER) && (_MSC_VER >= 1800)) || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__) /* * Same thing again, this time with C++11 ranges. */ { OpenMesh::PropertyManager< - OpenMesh::VPropHandleT, Mesh> pm_v_bool(mesh_, "pm_v_bool2"); + OpenMesh::VPropHandleT> pm_v_bool(mesh_, "pm_v_bool2"); pm_v_bool.set_range(mesh_.vertices(), false); for (int i = 0; i < 4; ++i) ASSERT_FALSE(pm_v_bool[vhandle[i]]); @@ -108,7 +116,7 @@ TEST_F(OpenMeshPropertyManager, set_range_bool) { ASSERT_TRUE(pm_v_bool[vhandle[i]]); OpenMesh::PropertyManager< - OpenMesh::EPropHandleT, Mesh> pm_e_bool(mesh_, "pm_e_bool2"); + OpenMesh::EPropHandleT> pm_e_bool(mesh_, "pm_e_bool2"); pm_e_bool.set_range(mesh_.edges(), false); for (Mesh::EdgeIter e_it = mesh_.edges_begin(), f_end = mesh_.edges_end(); e_it != f_end; ++e_it) @@ -119,7 +127,7 @@ TEST_F(OpenMeshPropertyManager, set_range_bool) { ASSERT_TRUE(pm_e_bool[*e_it]); OpenMesh::PropertyManager< - OpenMesh::FPropHandleT, Mesh> pm_f_bool(mesh_, "pm_f_bool2"); + OpenMesh::FPropHandleT> pm_f_bool(mesh_, "pm_f_bool2"); pm_f_bool.set_range(mesh_.faces(), false); for (Mesh::FaceIter f_it = mesh_.faces_begin(), f_end = mesh_.faces_end(); f_it != f_end; ++f_it) @@ -129,64 +137,6 @@ TEST_F(OpenMeshPropertyManager, set_range_bool) { f_it != f_end; ++f_it) ASSERT_TRUE(pm_f_bool[*f_it]); } -#endif -} - -/* - * ==================================================================== - * C++11 Specific Tests - * ==================================================================== - */ -#if (defined(_MSC_VER) && (_MSC_VER >= 1800)) || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__) - -template -bool has_property(const Mesh& _mesh, const std::string& _name) { - auto dummy_handle = PropHandle{}; - return _mesh.get_property_handle(dummy_handle, _name); -} - -/* - * Temporary property - */ -TEST_F(OpenMeshPropertyManager, cpp11_temp_property) { - using handle_type = OpenMesh::VPropHandleT; - const auto prop_name = "pm_v_test_property"; - ASSERT_FALSE(has_property(mesh_, prop_name)); - - { - auto vprop = OpenMesh::makePropertyManagerFromNew(mesh_, prop_name); - static_cast(vprop); // Unused variable - ASSERT_TRUE(has_property(mesh_, prop_name)); - } - - ASSERT_FALSE(has_property(mesh_, prop_name)); -} - -/* - * Two temporary properties on a mesh using the same name and type. The second - * (inner) one shadows the first (outer) one instead of aliasing. - */ -TEST_F(OpenMeshPropertyManager, cpp11_temp_property_shadowing) { - auto vh = mesh_.add_vertex({0,0,0}); // Dummy vertex to attach properties to - - using handle_type = OpenMesh::VPropHandleT; - const auto prop_name = "pm_v_test_property"; - - auto outer_prop = OpenMesh::makePropertyManagerFromNew(mesh_, prop_name); - outer_prop[vh] = 100; - ASSERT_EQ(100, outer_prop[vh]); - - { - // inner_prop uses same type and name as outer_prop - auto inner_prop = OpenMesh::makePropertyManagerFromNew(mesh_, prop_name); - inner_prop[vh] = 200; - ASSERT_EQ(200, inner_prop[vh]); - // End of scope: inner_prop is removed from mesh_ - } - - // Ensure outer_prop still exists and its data has not been overwritten by inner_prop - ASSERT_TRUE(has_property(mesh_, prop_name)); - ASSERT_EQ(100, outer_prop[vh]); } /* @@ -199,45 +149,726 @@ TEST_F(OpenMeshPropertyManager, cpp11_temp_property_shadowing) { TEST_F(OpenMeshPropertyManager, cpp11_persistent_and_non_owning_properties) { auto vh = mesh_.add_vertex({0,0,0}); // Dummy vertex to attach properties to - using handle_type = OpenMesh::VPropHandleT; const auto prop_name = "pm_v_test_property"; - ASSERT_FALSE(has_property(mesh_, prop_name)); + ASSERT_FALSE((OpenMesh::hasProperty(mesh_, prop_name))); { - auto prop = OpenMesh::makePropertyManagerFromExistingOrNew(mesh_, prop_name); + auto prop = OpenMesh::getOrMakeProperty(mesh_, prop_name); prop[vh] = 100; // End of scope, property persists } - ASSERT_TRUE(has_property(mesh_, prop_name)); + ASSERT_TRUE((OpenMesh::hasProperty(mesh_, prop_name))); { // Since a property of the same name and type already exists, this refers to the existing property. - auto prop = OpenMesh::makePropertyManagerFromExistingOrNew(mesh_, prop_name); + auto prop = OpenMesh::getOrMakeProperty(mesh_, prop_name); ASSERT_EQ(100, prop[vh]); prop[vh] = 200; // End of scope, property persists } - ASSERT_TRUE(has_property(mesh_, prop_name)); + ASSERT_TRUE((OpenMesh::hasProperty(mesh_, prop_name))); { // Acquire non-owning handle to the property, knowing it exists - auto prop = OpenMesh::makePropertyManagerFromExisting(mesh_, prop_name); + auto prop = OpenMesh::getProperty(mesh_, prop_name); ASSERT_EQ(200, prop[vh]); } - ASSERT_TRUE(has_property(mesh_, prop_name)); + ASSERT_TRUE((OpenMesh::hasProperty(mesh_, prop_name))); { // Attempt to acquire non-owning handle for a non-existing property - ASSERT_THROW(OpenMesh::makePropertyManagerFromExisting(mesh_, "wrong_property_name"), std::runtime_error); + auto code_that_throws = [&](){ + OpenMesh::getProperty(mesh_, "wrong_prop_name"); + }; + ASSERT_THROW(code_that_throws(), std::runtime_error); } - ASSERT_TRUE(has_property(mesh_, prop_name)); + ASSERT_TRUE((OpenMesh::hasProperty(mesh_, prop_name))); } -#endif + +TEST_F(OpenMeshPropertyManager, property_copy_construction) { + for (int i = 0; i < N_VERTICES_TIMING; ++i) + mesh_.add_vertex(Mesh::Point()); + + // unnamed + { + auto prop1 = OpenMesh::VProp(mesh_); + for (auto vh : mesh_.vertices()) + prop1[vh] = vh.idx()*2-13; + + auto prop2 = prop1; // prop1 and prop2 should be two different properties with the same content + + prop1.set_range(mesh_.vertices(), 0); + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13); + } + + // named + { + auto prop1 = OpenMesh::VProp(mesh_, "ids"); + for (auto vh : mesh_.vertices()) + prop1[vh] = vh.idx()*2-13; + + auto prop2 = prop1; // prop1 and prop2 should refere to the same property + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13); + + prop1.set_range(mesh_.vertices(), 0); + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0); + } +} + +TEST_F(OpenMeshPropertyManager, property_move_construction) { + for (int i = 0; i < N_VERTICES_TIMING; ++i) + mesh_.add_vertex(Mesh::Point()); + + // unnamed + { + auto prop1 = OpenMesh::VProp(mesh_); + for (auto vh : mesh_.vertices()) + prop1[vh] = vh.idx()*2-13; + + TIMING_OUTPUT(auto t_start = std::chrono::high_resolution_clock::now();) + auto prop2 = std::move(prop1); + TIMING_OUTPUT(auto t_end = std::chrono::high_resolution_clock::now();) + TIMING_OUTPUT(std::cout << "move constructing property from temporary took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl;) + + EXPECT_FALSE(prop1.isValid()) << "prop1 should have been invalidated"; + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13); + } + + // named + { + auto prop1 = OpenMesh::VProp(mesh_, "ids"); + for (auto vh : mesh_.vertices()) + prop1[vh] = vh.idx()*2-13; + + TIMING_OUTPUT(auto t_start = std::chrono::high_resolution_clock::now();) + auto prop2 = std::move(prop1); // prop1 and prop2 should refere to the same property + TIMING_OUTPUT(auto t_end = std::chrono::high_resolution_clock::now();) + TIMING_OUTPUT(std::cout << "move constructing from named took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl;) + + EXPECT_TRUE(prop1.isValid()) << "named properties cannot be invalidated"; + + EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], -13) << "property is not valid anymore"; + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "did not copy property correctly"; + + prop1.set_range(mesh_.vertices(), 0); + + EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], 0); + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0); + } +} + + +TEST_F(OpenMeshPropertyManager, property_copying_same_mesh) { + + for (int i = 0; i < N_VERTICES_TIMING; ++i) + mesh_.add_vertex(Mesh::Point()); + + // unnamed to unnamed + { + auto prop1 = OpenMesh::VProp(3, mesh_); + auto prop2 = OpenMesh::VProp(0, mesh_); + EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], 3) << "Property not initialized correctly"; + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + for (auto vh : mesh_.vertices()) + prop1[vh] = vh.idx()*2-13; + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + TIMING_OUTPUT(auto t_start = std::chrono::high_resolution_clock::now();) + prop2 = prop1; + TIMING_OUTPUT(auto t_end = std::chrono::high_resolution_clock::now();) + TIMING_OUTPUT(std::cout << "copying property temporary to temporary took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl;) + + EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], -13) << "Temporary property got destroyed"; + + prop1.set_range(mesh_.vertices(), 0); + + EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], 0) << "Property not copied correctly"; + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + } + + // unnamed to named + { + auto prop1 = OpenMesh::VProp(mesh_); + auto prop2 = OpenMesh::VProp(0, mesh_, "ids"); + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + for (auto vh : mesh_.vertices()) + prop1[vh] = vh.idx()*2-13; + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + TIMING_OUTPUT(auto t_start = std::chrono::high_resolution_clock::now();) + prop2 = prop1; + TIMING_OUTPUT(auto t_end = std::chrono::high_resolution_clock::now();) + TIMING_OUTPUT(std::cout << "copying property temporary to named took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl;) + + EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], -13) << "Temporary property got destroyed"; + + prop1.set_range(mesh_.vertices(), 0); + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + + auto prop3 = OpenMesh::VProp(mesh_, "ids"); + EXPECT_EQ(prop3[OpenMesh::VertexHandle(0)], -13) << "property with name 'ids' was not correctly changed"; + } + + // named to unnamed + { + auto prop1 = OpenMesh::VProp(mesh_, "ids2"); + auto prop2 = OpenMesh::VProp(mesh_); + prop2.set_range(mesh_.vertices(), 0); + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + for (auto vh : mesh_.vertices()) + prop1[vh] = vh.idx()*2-13; + + TIMING_OUTPUT(auto t_start = std::chrono::high_resolution_clock::now();) + prop2 = prop1; + TIMING_OUTPUT(auto t_end = std::chrono::high_resolution_clock::now();) + TIMING_OUTPUT(std::cout << "copying property named to temporary took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl;) + + prop1.set_range(mesh_.vertices(), 0); + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + + } + + // named to named (different names) + { + auto prop1 = OpenMesh::VProp(mesh_, "ids3"); + auto prop2 = OpenMesh::VProp(mesh_, "ids4"); + prop2.set_range(mesh_.vertices(), 0); + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + for (auto vh : mesh_.vertices()) + prop1[vh] = vh.idx()*2-13; + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + TIMING_OUTPUT(auto t_start = std::chrono::high_resolution_clock::now();) + prop2 = prop1; + TIMING_OUTPUT(auto t_end = std::chrono::high_resolution_clock::now();) + TIMING_OUTPUT(std::cout << "copying property named to named with different name took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl;) + + prop1.set_range(mesh_.vertices(), 0); + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + } + + // named to named (same names) + { + auto prop1 = OpenMesh::VProp(mesh_, "ids5"); + auto prop2 = OpenMesh::VProp(mesh_, "ids5"); + + for (auto vh : mesh_.vertices()) + prop1[vh] = vh.idx()*2-13; + + EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + + TIMING_OUTPUT(auto t_start = std::chrono::high_resolution_clock::now();) + prop2 = prop1; // this should be a no op + TIMING_OUTPUT(auto t_end = std::chrono::high_resolution_clock::now();) + TIMING_OUTPUT(std::cout << "copying property named to named with same name took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl;) + + EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + + prop1.set_range(mesh_.vertices(), 42); + + EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], 42) << "Property not copied correctly"; + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 42) << "Property not copied correctly"; + + auto prop3 = OpenMesh::VProp(mesh_, "ids5"); + EXPECT_EQ(prop3[OpenMesh::VertexHandle(0)], 42) << "Property not copied correctly"; + } + + { + auto prop1 = OpenMesh::MProp(mesh_); + *prop1 = 43; + auto prop2 = prop1; + + prop2 = prop1; + + prop2 = std::move(prop1); + } +} + + +TEST_F(OpenMeshPropertyManager, property_moving_same_mesh) { + + for (int i = 0; i < N_VERTICES_TIMING; ++i) + mesh_.add_vertex(Mesh::Point()); + + // unnamed to unnamed + { + auto prop1 = OpenMesh::VProp(mesh_); + auto prop2 = OpenMesh::VProp(mesh_); + prop2.set_range(mesh_.vertices(), 0); + + for (auto vh : mesh_.vertices()) + prop1[vh] = vh.idx()*2-13; + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + TIMING_OUTPUT(auto t_start = std::chrono::high_resolution_clock::now();) + prop2 = std::move(prop1); // this should be cheap + TIMING_OUTPUT(auto t_end = std::chrono::high_resolution_clock::now();) + TIMING_OUTPUT(std::cout << "moving property temporary to temporary took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl;) + + EXPECT_FALSE(prop1.isValid()) << "prop1 not invalidated after moving"; + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + } + + // unnamed to named + { + auto prop1 = OpenMesh::VProp(mesh_); + auto prop2 = OpenMesh::VProp(mesh_, "ids"); + prop2.set_range(mesh_.vertices(), 0); + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + for (auto vh : mesh_.vertices()) + prop1[vh] = vh.idx()*2-13; + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + TIMING_OUTPUT(auto t_start = std::chrono::high_resolution_clock::now();) + prop2 = std::move(prop1); + TIMING_OUTPUT(auto t_end = std::chrono::high_resolution_clock::now();) + TIMING_OUTPUT(std::cout << "moving property temporary to named took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl;) + + EXPECT_FALSE(prop1.isValid()) << "prop1 not invalidated after moving"; + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + + auto prop3 = OpenMesh::VProp(mesh_, "ids"); + EXPECT_EQ(prop3[OpenMesh::VertexHandle(0)], -13) << "property with name 'ids' was not correctly changed"; + } + + // named to unnamed + { + auto prop1 = OpenMesh::VProp(mesh_, "ids2"); + auto prop2 = OpenMesh::VProp(mesh_); + prop2.set_range(mesh_.vertices(), 0); + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + for (auto vh : mesh_.vertices()) + prop1[vh] = vh.idx()*2-13; + + TIMING_OUTPUT(auto t_start = std::chrono::high_resolution_clock::now();) + prop2 = std::move(prop1); // moving named properties will not invalidate the property and will copy the data + TIMING_OUTPUT(auto t_end = std::chrono::high_resolution_clock::now();) + TIMING_OUTPUT(std::cout << "moving property named to temporary took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl;) + + EXPECT_TRUE(prop1.isValid()) << "named prop1 should not be invalidated by moving"; + + prop1.set_range(mesh_.vertices(), 0); + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + + } + + // named to named (different names) + { + auto prop1 = OpenMesh::VProp(mesh_, "ids3"); + auto prop2 = OpenMesh::VProp(mesh_, "ids4"); + prop2.set_range(mesh_.vertices(), 0); + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + for (auto vh : mesh_.vertices()) + prop1[vh] = vh.idx()*2-13; + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + TIMING_OUTPUT(auto t_start = std::chrono::high_resolution_clock::now();) + prop2 = std::move(prop1); // moving named properties will not invalidate the property and will copy the data + TIMING_OUTPUT(auto t_end = std::chrono::high_resolution_clock::now();) + TIMING_OUTPUT(std::cout << "moving property named to named with different name took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl;) + + EXPECT_TRUE(prop1.isValid()) << "named prop1 should not be invalidated by moving"; + + prop1.set_range(mesh_.vertices(), 0); + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + } + + // named to named (same names) + { + auto prop1 = OpenMesh::VProp(mesh_, "ids5"); + auto prop2 = OpenMesh::VProp(mesh_, "ids5"); + + for (auto vh : mesh_.vertices()) + prop1[vh] = vh.idx()*2-13; + + EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + + TIMING_OUTPUT(auto t_start = std::chrono::high_resolution_clock::now();) + prop2 = std::move(prop1); // this should be a no op + TIMING_OUTPUT(auto t_end = std::chrono::high_resolution_clock::now();) + TIMING_OUTPUT(std::cout << "moving property named to named with same name took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl;) + + EXPECT_TRUE(prop1.isValid()) << "named prop1 should not be invalidated by moving"; + + EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + + prop1.set_range(mesh_.vertices(), 0); + + EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], 0) << "Property not copied correctly"; + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not copied correctly"; + + auto prop3 = OpenMesh::VProp(mesh_, "ids5"); + EXPECT_EQ(prop3[OpenMesh::VertexHandle(0)], 0) << "Property not copied correctly"; + } +} + + + +TEST_F(OpenMeshPropertyManager, property_copying_different_mesh) { + + for (int i = 0; i < N_VERTICES_TIMING; ++i) + mesh_.add_vertex(Mesh::Point()); + + auto copy = mesh_; + for (int i = 0; i < 10; ++i) + copy.add_vertex(Mesh::Point()); + + // unnamed to unnamed + { + auto prop1 = OpenMesh::VProp(3, mesh_); + auto prop2 = OpenMesh::VProp(0, copy); + EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], 3) << "Property not initialized correctly"; + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + for (auto vh : mesh_.vertices()) + prop1[vh] = vh.idx()*2-13; + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + TIMING_OUTPUT(auto t_start = std::chrono::high_resolution_clock::now();) + prop2 = prop1; + TIMING_OUTPUT(auto t_end = std::chrono::high_resolution_clock::now();) + TIMING_OUTPUT(std::cout << "copying property temporary to temporary took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl;) + + EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], -13) << "Temporary property got destroyed"; + + prop1.set_range(mesh_.vertices(), 0); + + EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], 0) << "Property not copied correctly"; + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + EXPECT_NO_FATAL_FAILURE(prop2[OpenMesh::VertexHandle(static_cast(copy.n_vertices())-1)]) << "Property not correctly resized"; + } + + // unnamed to named + { + auto prop1 = OpenMesh::VProp(mesh_); + auto prop2 = OpenMesh::VProp(0, copy, "ids"); + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + for (auto vh : mesh_.vertices()) + prop1[vh] = vh.idx()*2-13; + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + TIMING_OUTPUT(auto t_start = std::chrono::high_resolution_clock::now();) + prop2 = prop1; + TIMING_OUTPUT(auto t_end = std::chrono::high_resolution_clock::now();) + TIMING_OUTPUT(std::cout << "copying property temporary to named took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl;) + + EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], -13) << "Temporary property got destroyed"; + + prop1.set_range(mesh_.vertices(), 0); + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + + auto prop3 = OpenMesh::VProp(copy, "ids"); + EXPECT_EQ(prop3[OpenMesh::VertexHandle(0)], -13) << "property with name 'ids' was not correctly changed"; + } + + // named to unnamed + { + auto prop1 = OpenMesh::VProp(mesh_, "ids2"); + auto prop2 = OpenMesh::VProp(copy); + prop2.set_range(mesh_.vertices(), 0); + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + for (auto vh : mesh_.vertices()) + prop1[vh] = vh.idx()*2-13; + + TIMING_OUTPUT(auto t_start = std::chrono::high_resolution_clock::now();) + prop2 = prop1; + TIMING_OUTPUT(auto t_end = std::chrono::high_resolution_clock::now();) + TIMING_OUTPUT(std::cout << "copying property named to temporary took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl;) + + prop1.set_range(mesh_.vertices(), 0); + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + + } + + // named to named (different names) + { + auto prop1 = OpenMesh::VProp(mesh_, "ids3"); + auto prop2 = OpenMesh::VProp(copy, "ids4"); + prop2.set_range(mesh_.vertices(), 0); + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + for (auto vh : mesh_.vertices()) + prop1[vh] = vh.idx()*2-13; + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + TIMING_OUTPUT(auto t_start = std::chrono::high_resolution_clock::now();) + prop2 = prop1; + TIMING_OUTPUT(auto t_end = std::chrono::high_resolution_clock::now();) + TIMING_OUTPUT(std::cout << "copying property named to named with different name took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl;) + + prop1.set_range(mesh_.vertices(), 0); + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + } + + // named to named (same names) + { + auto prop1 = OpenMesh::VProp(mesh_, "ids5"); + auto prop2 = OpenMesh::VProp(copy, "ids5"); + + for (auto vh : mesh_.vertices()) + prop1[vh] = vh.idx()*2-13; + + EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + + TIMING_OUTPUT(auto t_start = std::chrono::high_resolution_clock::now();) + prop2 = prop1; // this should be a no op + TIMING_OUTPUT(auto t_end = std::chrono::high_resolution_clock::now();) + TIMING_OUTPUT(std::cout << "copying property named to named with same name took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl;) + + EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + + prop1.set_range(mesh_.vertices(), 42); + + EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], 42) << "Property not copied correctly"; + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + + auto prop3 = OpenMesh::VProp(mesh_, "ids5"); + EXPECT_EQ(prop3[OpenMesh::VertexHandle(0)], 42) << "Property not copied correctly"; + auto prop4 = OpenMesh::VProp(copy, "ids5"); + EXPECT_EQ(prop4[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + } +} + + +TEST_F(OpenMeshPropertyManager, property_moving_different_mesh) { + + for (int i = 0; i < N_VERTICES_TIMING; ++i) + mesh_.add_vertex(Mesh::Point()); + + auto copy = mesh_; + for (int i = 0; i < 10; ++i) + copy.add_vertex(Mesh::Point()); + + // unnamed to unnamed + { + auto prop1 = OpenMesh::VProp(mesh_); + auto prop2 = OpenMesh::VProp(copy); + prop2.set_range(mesh_.vertices(), 0); + + for (auto vh : mesh_.vertices()) + prop1[vh] = vh.idx()*2-13; + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + TIMING_OUTPUT(auto t_start = std::chrono::high_resolution_clock::now();) + prop2 = std::move(prop1); // this should be cheap + TIMING_OUTPUT(auto t_end = std::chrono::high_resolution_clock::now();) + TIMING_OUTPUT(std::cout << "moving property temporary to temporary took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl;) + + EXPECT_FALSE(prop1.isValid()) << "prop1 not invalidated after moving"; + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + EXPECT_NO_FATAL_FAILURE(prop2[OpenMesh::VertexHandle(static_cast(copy.n_vertices())-1)]) << "Property not correctly resized"; + } + + // unnamed to named + { + auto prop1 = OpenMesh::VProp(mesh_); + auto prop2 = OpenMesh::VProp(copy, "ids"); + prop2.set_range(mesh_.vertices(), 0); + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + for (auto vh : mesh_.vertices()) + prop1[vh] = vh.idx()*2-13; + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + TIMING_OUTPUT(auto t_start = std::chrono::high_resolution_clock::now();) + prop2 = std::move(prop1); + TIMING_OUTPUT(auto t_end = std::chrono::high_resolution_clock::now();) + TIMING_OUTPUT(std::cout << "moving property temporary to named took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl;) + + EXPECT_FALSE(prop1.isValid()) << "prop1 not invalidated after moving"; + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + + auto prop3 = OpenMesh::VProp(copy, "ids"); + EXPECT_EQ(prop3[OpenMesh::VertexHandle(0)], -13) << "property with name 'ids' was not correctly changed"; + } + + // named to unnamed + { + auto prop1 = OpenMesh::VProp(mesh_, "ids2"); + auto prop2 = OpenMesh::VProp(copy); + prop2.set_range(mesh_.vertices(), 0); + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + for (auto vh : mesh_.vertices()) + prop1[vh] = vh.idx()*2-13; + + TIMING_OUTPUT(auto t_start = std::chrono::high_resolution_clock::now();) + prop2 = std::move(prop1); // moving named properties will not invalidate the property and will copy the data + TIMING_OUTPUT(auto t_end = std::chrono::high_resolution_clock::now();) + TIMING_OUTPUT(std::cout << "moving property named to temporary took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl;) + + EXPECT_TRUE(prop1.isValid()) << "named prop1 should not be invalidated by moving"; + + prop1.set_range(mesh_.vertices(), 0); + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + + } + + // named to named (different names) + { + auto prop1 = OpenMesh::VProp(mesh_, "ids3"); + auto prop2 = OpenMesh::VProp(copy, "ids4"); + prop2.set_range(mesh_.vertices(), 0); + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + for (auto vh : mesh_.vertices()) + prop1[vh] = vh.idx()*2-13; + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + TIMING_OUTPUT(auto t_start = std::chrono::high_resolution_clock::now();) + prop2 = std::move(prop1); // moving named properties will not invalidate the property and will copy the data + TIMING_OUTPUT(auto t_end = std::chrono::high_resolution_clock::now();) + TIMING_OUTPUT(std::cout << "moving property named to named with different name took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl;) + + EXPECT_TRUE(prop1.isValid()) << "named prop1 should not be invalidated by moving"; + + prop1.set_range(mesh_.vertices(), 0); + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + } + + // named to named (same names) + { + auto prop1 = OpenMesh::VProp(mesh_, "ids5"); + auto prop2 = OpenMesh::VProp(copy, "ids5"); + + auto prop6 = OpenMesh::Prop(mesh_); + prop6 = prop1; + + for (auto vh : mesh_.vertices()) + prop1[vh] = vh.idx()*2-13; + + EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + + TIMING_OUTPUT(auto t_start = std::chrono::high_resolution_clock::now();) + prop2 = std::move(prop1); // should copy + TIMING_OUTPUT(auto t_end = std::chrono::high_resolution_clock::now();) + TIMING_OUTPUT(std::cout << "moving property named to named with same name took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl;) + + EXPECT_TRUE(prop1.isValid()) << "named prop1 should not be invalidated by moving"; + + EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + + prop1.set_range(mesh_.vertices(), 42); + + EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], 42) << "Property not copied correctly"; + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + + auto prop3 = OpenMesh::VProp(mesh_, "ids5"); + EXPECT_EQ(prop3[OpenMesh::VertexHandle(0)], 42) << "Property not copied correctly"; + auto prop4 = OpenMesh::VProp(copy, "ids5"); + EXPECT_EQ(prop4[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + } +} + + +TEST_F(OpenMeshPropertyManager, temporary_property_on_const_mesh) { + + const auto& const_ref = mesh_; + + auto cog = OpenMesh::FProp(const_ref); + auto points = OpenMesh::getPointsProperty(const_ref); + + for (auto fh : const_ref.faces()) + cog(fh) = fh.vertices().avg(points); + + auto cog_copy = cog; + + for (auto fh : const_ref.faces()) + { + EXPECT_NE(&cog(fh), &cog_copy(fh)) << "Both properties point to the same memory"; + EXPECT_EQ(cog(fh), cog_copy(fh)) << "Property not copied correctly"; + } + + auto description = OpenMesh::MProp(const_ref); + description() = "Cool Const Mesh"; + + std::cout << description(OpenMesh::MeshHandle(33)) << std::endl; + +} + + +OpenMesh::VProp get_id_prop(const OpenMesh::PolyConnectivity& mesh) +{ + TIMING_OUTPUT(auto t_start = std::chrono::high_resolution_clock::now();) + + auto id_prop = OpenMesh::VProp(mesh); + for (auto vh : mesh.vertices()) + id_prop(vh) = vh.idx(); + + TIMING_OUTPUT(auto t_end = std::chrono::high_resolution_clock::now();) + TIMING_OUTPUT(std::cout << "Time spend in function: " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl;) + + return id_prop; +} + +TEST_F(OpenMeshPropertyManager, return_property_from_function) { + + for (int i = 0; i < N_VERTICES_TIMING; ++i) + mesh_.add_vertex(Mesh::Point()); + + TIMING_OUTPUT(auto t_start = std::chrono::high_resolution_clock::now();) + auto id_p = get_id_prop(mesh_); + TIMING_OUTPUT(auto t_end = std::chrono::high_resolution_clock::now();) + TIMING_OUTPUT(std::cout << "Time spend around function " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl;) + + for (auto vh : mesh_.vertices()) + { + EXPECT_EQ(id_p(vh), vh.idx()) << "Property not returned correctly" << std::endl; + } + +} + + } diff --git a/src/Unittests/unittests_read_write_OBJ.cc b/src/Unittests/unittests_read_write_OBJ.cc index 6d6019fe..c779daa0 100644 --- a/src/Unittests/unittests_read_write_OBJ.cc +++ b/src/Unittests/unittests_read_write_OBJ.cc @@ -325,9 +325,16 @@ TEST_F(OpenMeshReadWriteOBJ, LoadObjWithMaterial) { EXPECT_TRUE(fh.is_valid()) << "fh should be valid"; +#ifdef TEST_DOUBLE_TRAITS + EXPECT_FLOAT_EQ(128/255.0, mesh_.color(fh)[0] ) << "Wrong vertex color at vertex 0 component 0"; + EXPECT_FLOAT_EQ(128/255.0, mesh_.color(fh)[1] ) << "Wrong vertex color at vertex 0 component 1"; + EXPECT_FLOAT_EQ(128/255.0, mesh_.color(fh)[2] ) << "Wrong vertex color at vertex 0 component 2"; + EXPECT_FLOAT_EQ(1.0, mesh_.color(fh)[3] ) << "Wrong vertex color at vertex 0 component 3"; +#else EXPECT_EQ(128, mesh_.color(fh)[0] ) << "Wrong vertex color at vertex 0 component 0"; EXPECT_EQ(128, mesh_.color(fh)[1] ) << "Wrong vertex color at vertex 0 component 1"; EXPECT_EQ(128, mesh_.color(fh)[2] ) << "Wrong vertex color at vertex 0 component 2"; +#endif mesh_.release_face_colors(); } @@ -385,6 +392,24 @@ TEST_F(OpenMeshReadWriteOBJ, LoadSimpleOBJWithVertexColorsAfterVertices) { EXPECT_EQ(18u , mesh_.n_edges()) << "The number of loaded edges is not correct!"; EXPECT_EQ(12u , mesh_.n_faces()) << "The number of loaded faces is not correct!"; + +#ifdef TEST_DOUBLE_TRAITS + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(0))[0] ) << "Wrong vertex color at vertex 0 component 0"; + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(0))[1] ) << "Wrong vertex color at vertex 0 component 1"; + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(0))[2] ) << "Wrong vertex color at vertex 0 component 2"; + + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(3))[0] ) << "Wrong vertex color at vertex 3 component 0"; + EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(3))[1] ) << "Wrong vertex color at vertex 3 component 1"; + EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(3))[2] ) << "Wrong vertex color at vertex 3 component 2"; + + EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(4))[0] ) << "Wrong vertex color at vertex 4 component 0"; + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(4))[1] ) << "Wrong vertex color at vertex 4 component 1"; + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(4))[2] ) << "Wrong vertex color at vertex 4 component 2"; + + EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(7))[0] ) << "Wrong vertex color at vertex 7 component 0"; + EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(7))[1] ) << "Wrong vertex color at vertex 7 component 1"; + EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(7))[2] ) << "Wrong vertex color at vertex 7 component 2"; +#else EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[0] ) << "Wrong vertex color at vertex 0 component 0"; EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[1] ) << "Wrong vertex color at vertex 0 component 1"; EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[2] ) << "Wrong vertex color at vertex 0 component 2"; @@ -400,6 +425,7 @@ TEST_F(OpenMeshReadWriteOBJ, LoadSimpleOBJWithVertexColorsAfterVertices) { EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(7))[0] ) << "Wrong vertex color at vertex 7 component 0"; EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(7))[1] ) << "Wrong vertex color at vertex 7 component 1"; EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(7))[2] ) << "Wrong vertex color at vertex 7 component 2"; +#endif mesh_.release_vertex_colors(); } @@ -424,6 +450,23 @@ TEST_F(OpenMeshReadWriteOBJ, LoadSimpleOBJWithVertexColorsAsVCLines) { EXPECT_EQ(18u , mesh_.n_edges()) << "The number of loaded edges is not correct!"; EXPECT_EQ(12u , mesh_.n_faces()) << "The number of loaded faces is not correct!"; +#ifdef TEST_DOUBLE_TRAITS + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(0))[0] ) << "Wrong vertex color at vertex 0 component 0"; + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(0))[1] ) << "Wrong vertex color at vertex 0 component 1"; + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(0))[2] ) << "Wrong vertex color at vertex 0 component 2"; + + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(3))[0] ) << "Wrong vertex color at vertex 3 component 0"; + EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(3))[1] ) << "Wrong vertex color at vertex 3 component 1"; + EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(3))[2] ) << "Wrong vertex color at vertex 3 component 2"; + + EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(4))[0] ) << "Wrong vertex color at vertex 4 component 0"; + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(4))[1] ) << "Wrong vertex color at vertex 4 component 1"; + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(4))[2] ) << "Wrong vertex color at vertex 4 component 2"; + + EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(7))[0] ) << "Wrong vertex color at vertex 7 component 0"; + EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(7))[1] ) << "Wrong vertex color at vertex 7 component 1"; + EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(7))[2] ) << "Wrong vertex color at vertex 7 component 2"; +#else EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[0] ) << "Wrong vertex color at vertex 0 component 0"; EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[1] ) << "Wrong vertex color at vertex 0 component 1"; EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[2] ) << "Wrong vertex color at vertex 0 component 2"; @@ -439,6 +482,7 @@ TEST_F(OpenMeshReadWriteOBJ, LoadSimpleOBJWithVertexColorsAsVCLines) { EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(7))[0] ) << "Wrong vertex color at vertex 7 component 0"; EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(7))[1] ) << "Wrong vertex color at vertex 7 component 1"; EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(7))[2] ) << "Wrong vertex color at vertex 7 component 2"; +#endif mesh_.release_vertex_colors(); @@ -499,4 +543,88 @@ TEST_F(OpenMeshReadWriteOBJ, ReadWriteReadSimpleOBJ) { EXPECT_EQ(1, mesh2.normal(mesh2.vertex_handle(7))[2] ) << "Wrong vertex normal at vertex 7 component 2"; } + + +TEST_F(OpenMeshReadWriteOBJ, FaceTexCoordTest) { + + mesh_.clear(); + mesh_.request_vertex_normals(); + mesh_.request_halfedge_texcoords2D(); + + // Add some vertices + Mesh::VertexHandle vhandle[5]; + + vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 0, 0)); + vhandle[1] = mesh_.add_vertex(Mesh::Point(0, 1, 0)); + vhandle[2] = mesh_.add_vertex(Mesh::Point(1, 1, 0)); + + // Add one face + std::vector face_vhandles; + + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[0]); + + Mesh::FaceHandle fh = mesh_.add_face(face_vhandles); + + // 1 --- 2 + // | / + // | / + // | / + // 0 + + mesh_.set_normal(vhandle[0] , Mesh::Normal(1,0,0)); + mesh_.set_normal(vhandle[1] , Mesh::Normal(0,1,0)); + mesh_.set_normal(vhandle[2] , Mesh::Normal(0,0,1)); + + + float u = 8.0f; + for ( auto he : mesh_.halfedges() ) { + + mesh_.set_texcoord2D(he,Mesh::TexCoord2D(u,u)); + u += 1.0; + } + + + u = 0.0f; + + for ( auto he : mesh_.fh_range(fh) ) + { + + mesh_.set_texcoord2D(he,Mesh::TexCoord2D(u,u)); + u += 1.0f; + } + + + + OpenMesh::IO::Options wopt; + wopt += OpenMesh::IO::Options::VertexNormal; + wopt += OpenMesh::IO::Options::FaceTexCoord; + + bool ok = OpenMesh::IO::write_mesh(mesh_, "OpenMeshReadWriteOBJ_FaceTexCoordTest.obj", wopt); + + EXPECT_TRUE(ok) << "Unable to write OpenMeshReadWriteOBJ_FaceTexCoordTest.obj"; + + mesh_.clear(); + + + OpenMesh::IO::Options ropt; + + ropt += OpenMesh::IO::Options::FaceTexCoord; + + mesh_.request_vertex_normals(); + mesh_.request_face_normals(); + mesh_.request_halfedge_texcoords2D(); + + ok = OpenMesh::IO::read_mesh(mesh_, "OpenMeshReadWriteOBJ_FaceTexCoordTest.obj", ropt); + + EXPECT_TRUE(ok) << "Unable to read back OpenMeshReadWriteOBJ_FaceTexCoordTest.obj"; + +} + + + + + + } diff --git a/src/Unittests/unittests_read_write_OFF.cc b/src/Unittests/unittests_read_write_OFF.cc index 0a9684ed..1f26647c 100644 --- a/src/Unittests/unittests_read_write_OFF.cc +++ b/src/Unittests/unittests_read_write_OFF.cc @@ -60,8 +60,13 @@ TEST_F(OpenMeshReadWriteOFF, WriteAndReadVertexColorsToAndFromOFFFile) { mesh_.add_vertex( Mesh::Point(0,1,1) ); mesh_.add_vertex( Mesh::Point(1,0,1) ); +#ifdef TEST_DOUBLE_TRAITS + // using the default color type Vec4f from DefaultTraitsDouble in Traits.hh + Mesh::Color testColor(255/255.0, 128/255.0, 64/255.0, 1.0); +#else // using the default color type Vec3uc from DefaultTraits in Traits.hh Mesh::Color testColor(255, 128, 64); +#endif // setting colors (different from black) for (Mesh::VertexIter vit = mesh_.vertices_begin(), vitend = mesh_.vertices_end(); vit != vitend; ++vit) @@ -71,7 +76,10 @@ TEST_F(OpenMeshReadWriteOFF, WriteAndReadVertexColorsToAndFromOFFFile) { int count = 0; for (Mesh::VertexIter vit = mesh_.vertices_begin(), vitend = mesh_.vertices_end(); vit != vitend; ++vit) { Mesh::Color color = mesh_.color(*vit); - if ( color[0] != testColor[0] || color[1] != testColor[1] || color[2] != testColor[2] ) + bool wrong_color = false; + for (size_t i = 0; i < color.size(); ++i) + wrong_color = wrong_color || (color[i] != testColor[i]); + if (wrong_color) ++ count; } @@ -87,7 +95,10 @@ TEST_F(OpenMeshReadWriteOFF, WriteAndReadVertexColorsToAndFromOFFFile) { count = 0; for (Mesh::VertexIter vit = mesh_.vertices_begin(), vitend = mesh_.vertices_end(); vit != vitend; ++vit) { Mesh::Color color = mesh_.color(*vit); - if ( color[0] != testColor[0] || color[1] != testColor[1] || color[2] != testColor[2] ) + bool wrong_color = false; + for (size_t i = 0; i < color.size(); ++i) + wrong_color = wrong_color || (color[i] != testColor[i]); + if (wrong_color) ++ count; } @@ -123,21 +134,39 @@ TEST_F(OpenMeshReadWriteOFF, WriteAndReadFloatVertexColorsToAndFromOFFFile) { EXPECT_EQ(18u , mesh_.n_edges()) << "The number of loaded edges is not correct!"; EXPECT_EQ(12u , mesh_.n_faces()) << "The number of loaded faces is not correct!"; +#ifdef TEST_DOUBLE_TRAITS + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(0))[0] ) << "Wrong vertex color at vertex 0 component 0"; + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(0))[1] ) << "Wrong vertex color at vertex 0 component 1"; + EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(0))[2] ) << "Wrong vertex color at vertex 0 component 2"; + + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(3))[0] ) << "Wrong vertex color at vertex 3 component 0"; + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(3))[1] ) << "Wrong vertex color at vertex 3 component 1"; + EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(3))[2] ) << "Wrong vertex color at vertex 3 component 2"; + + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(4))[0] ) << "Wrong vertex color at vertex 4 component 0"; + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(4))[1] ) << "Wrong vertex color at vertex 4 component 1"; + EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(4))[2] ) << "Wrong vertex color at vertex 4 component 2"; + + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(7))[0] ) << "Wrong vertex color at vertex 7 component 0"; + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(7))[1] ) << "Wrong vertex color at vertex 7 component 1"; + EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(7))[2] ) << "Wrong vertex color at vertex 7 component 2"; +#else EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[0] ) << "Wrong vertex color at vertex 0 component 0"; EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[1] ) << "Wrong vertex color at vertex 0 component 1"; - EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(0))[2] ) << "Wrong vertex color at vertex 0 component 2"; + EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(0))[2] ) << "Wrong vertex color at vertex 0 component 2"; EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[0] ) << "Wrong vertex color at vertex 3 component 0"; - EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[1] ) << "Wrong vertex color at vertex 3 component 1"; + EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[1] ) << "Wrong vertex color at vertex 3 component 1"; EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(3))[2] ) << "Wrong vertex color at vertex 3 component 2"; - EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[0] ) << "Wrong vertex color at vertex 4 component 0"; + EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[0] ) << "Wrong vertex color at vertex 4 component 0"; EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[1] ) << "Wrong vertex color at vertex 4 component 1"; - EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(4))[2] ) << "Wrong vertex color at vertex 4 component 2"; + EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(4))[2] ) << "Wrong vertex color at vertex 4 component 2"; - EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[0] ) << "Wrong vertex color at vertex 7 component 0"; - EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[1] ) << "Wrong vertex color at vertex 7 component 1"; + EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[0] ) << "Wrong vertex color at vertex 7 component 0"; + EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[1] ) << "Wrong vertex color at vertex 7 component 1"; EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(7))[2] ) << "Wrong vertex color at vertex 7 component 2"; +#endif EXPECT_FALSE(opt.vertex_has_normal()) << "Wrong user opt are returned!"; EXPECT_FALSE(opt.vertex_has_texcoord()) << "Wrong user opt are returned!"; @@ -179,21 +208,39 @@ TEST_F(OpenMeshReadWriteOFF, WriteAndReadBinaryFloatVertexColorsToAndFromOFFFile EXPECT_EQ(18u , mesh_.n_edges()) << "The number of loaded edges is not correct!"; EXPECT_EQ(12u , mesh_.n_faces()) << "The number of loaded faces is not correct!"; +#ifdef TEST_DOUBLE_TRAITS + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(0))[0] ) << "Wrong vertex color at vertex 0 component 0"; + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(0))[1] ) << "Wrong vertex color at vertex 0 component 1"; + EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(0))[2] ) << "Wrong vertex color at vertex 0 component 2"; + + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(3))[0] ) << "Wrong vertex color at vertex 3 component 0"; + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(3))[1] ) << "Wrong vertex color at vertex 3 component 1"; + EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(3))[2] ) << "Wrong vertex color at vertex 3 component 2"; + + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(4))[0] ) << "Wrong vertex color at vertex 4 component 0"; + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(4))[1] ) << "Wrong vertex color at vertex 4 component 1"; + EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(4))[2] ) << "Wrong vertex color at vertex 4 component 2"; + + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(7))[0] ) << "Wrong vertex color at vertex 7 component 0"; + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(7))[1] ) << "Wrong vertex color at vertex 7 component 1"; + EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(7))[2] ) << "Wrong vertex color at vertex 7 component 2"; +#else EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[0] ) << "Wrong vertex color at vertex 0 component 0"; EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[1] ) << "Wrong vertex color at vertex 0 component 1"; - EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(0))[2] ) << "Wrong vertex color at vertex 0 component 2"; + EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(0))[2] ) << "Wrong vertex color at vertex 0 component 2"; EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[0] ) << "Wrong vertex color at vertex 3 component 0"; - EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[1] ) << "Wrong vertex color at vertex 3 component 1"; + EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[1] ) << "Wrong vertex color at vertex 3 component 1"; EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(3))[2] ) << "Wrong vertex color at vertex 3 component 2"; - EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[0] ) << "Wrong vertex color at vertex 4 component 0"; + EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[0] ) << "Wrong vertex color at vertex 4 component 0"; EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[1] ) << "Wrong vertex color at vertex 4 component 1"; - EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(4))[2] ) << "Wrong vertex color at vertex 4 component 2"; + EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(4))[2] ) << "Wrong vertex color at vertex 4 component 2"; - EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[0] ) << "Wrong vertex color at vertex 7 component 0"; - EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[1] ) << "Wrong vertex color at vertex 7 component 1"; + EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[0] ) << "Wrong vertex color at vertex 7 component 0"; + EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[1] ) << "Wrong vertex color at vertex 7 component 1"; EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(7))[2] ) << "Wrong vertex color at vertex 7 component 2"; +#endif EXPECT_FALSE(opt.vertex_has_normal()) << "Wrong user opt are returned!"; EXPECT_FALSE(opt.vertex_has_texcoord()) << "Wrong user opt are returned!"; diff --git a/src/Unittests/unittests_read_write_OM.cc b/src/Unittests/unittests_read_write_OM.cc index 4d33486e..35e4522d 100644 --- a/src/Unittests/unittests_read_write_OM.cc +++ b/src/Unittests/unittests_read_write_OM.cc @@ -72,7 +72,7 @@ TEST_F(OpenMeshReadWriteOM, LoadSimpleOMWithTexCoords) { bool ok = OpenMesh::IO::read_mesh(mesh_, "cube-minimal-texCoords.om",options); - EXPECT_TRUE(ok) << "Unable to load cube-minimal-texCoords.om"; + ASSERT_TRUE(ok) << "Unable to load cube-minimal-texCoords.om"; EXPECT_EQ(8u , mesh_.n_vertices()) << "The number of loaded vertices is not correct!"; EXPECT_EQ(18u , mesh_.n_edges()) << "The number of loaded edges is not correct!"; @@ -118,21 +118,39 @@ TEST_F(OpenMeshReadWriteOM, LoadSimpleOMWithVertexColors) { EXPECT_EQ(18u , mesh_.n_edges()) << "The number of loaded edges is not correct!"; EXPECT_EQ(12u , mesh_.n_faces()) << "The number of loaded faces is not correct!"; - EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(0))[0] ) << "Wrong vertex color at vertex 0 component 0"; +#ifdef TEST_DOUBLE_TRAITS + EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(0))[0] ) << "Wrong vertex color at vertex 0 component 0"; + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(0))[1] ) << "Wrong vertex color at vertex 0 component 1"; + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(0))[2] ) << "Wrong vertex color at vertex 0 component 2"; + + EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(3))[0] ) << "Wrong vertex color at vertex 3 component 0"; + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(3))[1] ) << "Wrong vertex color at vertex 3 component 1"; + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(3))[2] ) << "Wrong vertex color at vertex 3 component 2"; + + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(4))[0] ) << "Wrong vertex color at vertex 4 component 0"; + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(4))[1] ) << "Wrong vertex color at vertex 4 component 1"; + EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(4))[2] ) << "Wrong vertex color at vertex 4 component 2"; + + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(7))[0] ) << "Wrong vertex color at vertex 7 component 0"; + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(7))[1] ) << "Wrong vertex color at vertex 7 component 1"; + EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(7))[2] ) << "Wrong vertex color at vertex 7 component 2"; +#else + EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(0))[0] ) << "Wrong vertex color at vertex 0 component 0"; EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[1] ) << "Wrong vertex color at vertex 0 component 1"; EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[2] ) << "Wrong vertex color at vertex 0 component 2"; - EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(3))[0] ) << "Wrong vertex color at vertex 3 component 0"; - EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[1] ) << "Wrong vertex color at vertex 3 component 1"; - EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[2] ) << "Wrong vertex color at vertex 3 component 2"; + EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(3))[0] ) << "Wrong vertex color at vertex 3 component 0"; + EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[1] ) << "Wrong vertex color at vertex 3 component 1"; + EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[2] ) << "Wrong vertex color at vertex 3 component 2"; - EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[0] ) << "Wrong vertex color at vertex 4 component 0"; + EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[0] ) << "Wrong vertex color at vertex 4 component 0"; EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[1] ) << "Wrong vertex color at vertex 4 component 1"; - EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(4))[2] ) << "Wrong vertex color at vertex 4 component 2"; + EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(4))[2] ) << "Wrong vertex color at vertex 4 component 2"; - EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[0] ) << "Wrong vertex color at vertex 7 component 0"; - EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[1] ) << "Wrong vertex color at vertex 7 component 1"; + EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[0] ) << "Wrong vertex color at vertex 7 component 0"; + EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[1] ) << "Wrong vertex color at vertex 7 component 1"; EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(7))[2] ) << "Wrong vertex color at vertex 7 component 2"; +#endif EXPECT_FALSE(options.vertex_has_normal()) << "Wrong user options are returned!"; EXPECT_FALSE(options.vertex_has_texcoord()) << "Wrong user options are returned!"; @@ -203,9 +221,15 @@ TEST_F(OpenMeshReadWriteOM, WriteTriangleVertexIntegerColor) { Mesh::VertexHandle v3 = mesh.add_vertex(Mesh::Point(0.0,0.0,1.0)); mesh.add_face(v1,v2,v3); +#ifdef TEST_DOUBLE_TRAITS + Mesh::Color c1 = Mesh::Color(0,0,123/255.0,1.0), + c2 = Mesh::Color(21/255.0,0,0,1.0), + c3 = Mesh::Color(0,222/255.0,0,1.0); +#else Mesh::Color c1 = Mesh::Color(0,0,123), c2 = Mesh::Color(21,0,0), c3 = Mesh::Color(0,222,0); +#endif mesh.set_color(v1,c1); mesh.set_color(v2,c2); @@ -234,9 +258,20 @@ TEST_F(OpenMeshReadWriteOM, WriteTriangleVertexIntegerColor) { EXPECT_EQ(Mesh::Point(0.0,1.0,0.0) , cmpMesh.point(v2)) << "Wrong coordinates at vertex 1"; EXPECT_EQ(Mesh::Point(0.0,0.0,1.0) , cmpMesh.point(v3)) << "Wrong coordinates at vertex 2"; +#ifdef TEST_DOUBLE_TRAITS + // OM file format does not support writing colors as float. They are stored as unsigned character. + // Thus, the values will not be exactly equal. + for (size_t i = 0; i < c1.size(); ++i) + { + EXPECT_FLOAT_EQ(c1[i] , cmpMesh.color(v1)[i]) << "Wrong colors at coordinate " << i << " of vertex 0"; + EXPECT_FLOAT_EQ(c2[i] , cmpMesh.color(v2)[i]) << "Wrong colors at coordinate " << i << " of vertex 1"; + EXPECT_FLOAT_EQ(c3[i] , cmpMesh.color(v3)[i]) << "Wrong colors at coordinate " << i << " of vertex 2"; + } +#else EXPECT_EQ(c1 , cmpMesh.color(v1)) << "Wrong colors at vertex 0"; EXPECT_EQ(c2 , cmpMesh.color(v2)) << "Wrong colors at vertex 1"; EXPECT_EQ(c3 , cmpMesh.color(v3)) << "Wrong colors at vertex 2"; +#endif //clean up cmpMesh.release_vertex_colors(); @@ -464,11 +499,11 @@ TEST_F(OpenMeshReadWriteOM, WriteTriangleEdgeIntProperty) { Mesh::EdgeHandle e2 = Mesh::EdgeHandle(1); Mesh::EdgeHandle e3 = Mesh::EdgeHandle(2); - int va1ue1 = 10, + int value1 = 10, value2 = 21, value3 = 32; - mesh.property(prop,e1) = va1ue1; + mesh.property(prop,e1) = value1; mesh.property(prop,e2) = value2; mesh.property(prop,e3) = value3; @@ -494,7 +529,7 @@ TEST_F(OpenMeshReadWriteOM, WriteTriangleEdgeIntProperty) { EXPECT_EQ(Mesh::Point(0.0,1.0,0.0) , cmpMesh.point(v2)) << "Wrong coordinates at vertex 1"; EXPECT_EQ(Mesh::Point(0.0,0.0,1.0) , cmpMesh.point(v3)) << "Wrong coordinates at vertex 2"; - EXPECT_EQ(va1ue1 , cmpMesh.property(prop,e1)) << "Wrong property at edge 0"; + EXPECT_EQ(value1 , cmpMesh.property(prop,e1)) << "Wrong property at edge 0"; EXPECT_EQ(value2 , cmpMesh.property(prop,e2)) << "Wrong property at edge 1"; EXPECT_EQ(value3 , cmpMesh.property(prop,e3)) << "Wrong property at edge 2"; @@ -503,6 +538,308 @@ TEST_F(OpenMeshReadWriteOM, WriteTriangleEdgeIntProperty) { } +/* + * Save and load simple mesh with custom property + */ +TEST_F(OpenMeshReadWriteOM, WriteSplitTriangleEdgeIntProperty) { + + Mesh mesh; + + const std::string propName = "EIProp"; + const std::string filename = std::string("triangle-minimal-")+propName+".om"; + + // generate data + Mesh::VertexHandle v1 = mesh.add_vertex(Mesh::Point(1.0,0.0,0.0)); + Mesh::VertexHandle v2 = mesh.add_vertex(Mesh::Point(0.0,1.0,0.0)); + Mesh::VertexHandle v3 = mesh.add_vertex(Mesh::Point(0.0,0.0,1.0)); + auto fh0 = mesh.add_face(v1,v2,v3); + auto c = mesh.calc_face_centroid(fh0); + Mesh::VertexHandle v4 = mesh.add_vertex(c); + mesh.split(fh0, v4); + + + OpenMesh::EPropHandleT prop; + mesh.add_property(prop,propName); + mesh.property(prop).set_persistent(true); + + Mesh::EdgeHandle e1 = Mesh::EdgeHandle(0); + Mesh::EdgeHandle e2 = Mesh::EdgeHandle(1); + Mesh::EdgeHandle e3 = Mesh::EdgeHandle(2); + Mesh::EdgeHandle e4 = Mesh::EdgeHandle(3); + Mesh::EdgeHandle e5 = Mesh::EdgeHandle(4); + Mesh::EdgeHandle e6 = Mesh::EdgeHandle(5); + + int value1 = 10, + value2 = 21, + value3 = 32, + value4 = 43, + value5 = 54, + value6 = 65; + + mesh.property(prop,e1) = value1; + mesh.property(prop,e2) = value2; + mesh.property(prop,e3) = value3; + mesh.property(prop,e4) = value4; + mesh.property(prop,e5) = value5; + mesh.property(prop,e6) = value6; + + // save + OpenMesh::IO::Options options; + bool ok = OpenMesh::IO::write_mesh(mesh,filename); + EXPECT_TRUE(ok) << "Unable to write "< vertex_deleted; + std::vector vertex_selected; + std::vector vertex_feature; + std::vector vertex_tagged; + std::vector vertex_tagged2; + + for (auto vh : mesh.all_vertices()) + { + vertex_deleted.push_back(mesh.status(vh).deleted()); + vertex_selected.push_back(mesh.status(vh).selected()); + vertex_feature.push_back(mesh.status(vh).feature()); + vertex_tagged.push_back(mesh.status(vh).tagged()); + vertex_tagged2.push_back(mesh.status(vh).tagged2()); + } + + Mesh::EdgeHandle e1 = Mesh::EdgeHandle(0); + Mesh::EdgeHandle e2 = Mesh::EdgeHandle(1); + Mesh::EdgeHandle e3 = Mesh::EdgeHandle(2); + Mesh::EdgeHandle e4 = Mesh::EdgeHandle(3); + + mesh.status(e1).set_selected(true); + mesh.status(e2).set_feature(true); + mesh.status(e3).set_tagged(true); + mesh.status(e4).set_tagged2(true); + + std::vector edge_deleted; + std::vector edge_selected; + std::vector edge_feature; + std::vector edge_tagged; + std::vector edge_tagged2; + + for (auto eh : mesh.all_edges()) + { + edge_deleted.push_back(mesh.status(eh).deleted()); + edge_selected.push_back(mesh.status(eh).selected()); + edge_feature.push_back(mesh.status(eh).feature()); + edge_tagged.push_back(mesh.status(eh).tagged()); + edge_tagged2.push_back(mesh.status(eh).tagged2()); + } + + + Mesh::HalfedgeHandle he1 = Mesh::HalfedgeHandle(0); + Mesh::HalfedgeHandle he2 = Mesh::HalfedgeHandle(3); + Mesh::HalfedgeHandle he3 = Mesh::HalfedgeHandle(5); + Mesh::HalfedgeHandle he4 = Mesh::HalfedgeHandle(1); + + mesh.status(he1).set_selected(true); + mesh.status(he2).set_feature(true); + mesh.status(he3).set_tagged(true); + mesh.status(he4).set_tagged2(true); + + std::vector halfedge_deleted; + std::vector halfedge_selected; + std::vector halfedge_feature; + std::vector halfedge_tagged; + std::vector halfedge_tagged2; + + for (auto heh : mesh.all_halfedges()) + { + halfedge_deleted.push_back(mesh.status(heh).deleted()); + halfedge_selected.push_back(mesh.status(heh).selected()); + halfedge_feature.push_back(mesh.status(heh).feature()); + halfedge_tagged.push_back(mesh.status(heh).tagged()); + halfedge_tagged2.push_back(mesh.status(heh).tagged2()); + } + + Mesh::FaceHandle f1 = Mesh::FaceHandle(0); + Mesh::FaceHandle f2 = Mesh::FaceHandle(2); + Mesh::FaceHandle f3 = Mesh::FaceHandle(1); + Mesh::FaceHandle f4 = Mesh::FaceHandle(2); + + mesh.status(f1).set_selected(true); + mesh.status(f2).set_feature(true); + mesh.status(f3).set_tagged(true); + mesh.status(f4).set_tagged2(true); + + std::vector face_deleted; + std::vector face_selected; + std::vector face_feature; + std::vector face_tagged; + std::vector face_tagged2; + + for (auto fh : mesh.all_faces()) + { + face_deleted.push_back(mesh.status(fh).deleted()); + face_selected.push_back(mesh.status(fh).selected()); + face_feature.push_back(mesh.status(fh).feature()); + face_tagged.push_back(mesh.status(fh).tagged()); + face_tagged2.push_back(mesh.status(fh).tagged2()); + } + + // save + OpenMesh::IO::Options options = OpenMesh::IO::Options::Status; + bool ok = OpenMesh::IO::write_mesh(mesh,filename, options); + EXPECT_TRUE(ok) << "Unable to write "< DoublePolyMesh; + + DoublePolyMesh mesh; + mesh.request_vertex_normals(); + mesh.request_face_normals(); + + std::vector vertices; + for (int i = 0; i < 3; ++i) + { + vertices.push_back(mesh.add_vertex(DoublePolyMesh::Point(1.0/3.0, std::numeric_limits::min(), std::numeric_limits::max()))); + mesh.set_normal(vertices.back(), DoublePolyMesh::Normal(1.0/3.0, std::numeric_limits::min(), std::numeric_limits::max())); + } + auto fh = mesh.add_face(vertices); + mesh.set_normal(fh, DoublePolyMesh::Normal(1.0/3.0, std::numeric_limits::min(), std::numeric_limits::max())); + + std::string file_name = "doubles.om"; + + OpenMesh::IO::Options opt = OpenMesh::IO::Options::VertexNormal | OpenMesh::IO::Options::FaceNormal; + ASSERT_TRUE(OpenMesh::IO::write_mesh(mesh, file_name, opt)) << "Could not write file " << file_name; + + DoublePolyMesh mesh2; + mesh2.request_vertex_normals(); + mesh2.request_face_normals(); + + ASSERT_TRUE(OpenMesh::IO::read_mesh(mesh2, file_name, opt)) << "Could not read file " << file_name; + + EXPECT_EQ(mesh.point(OpenMesh::VertexHandle(0)), mesh2.point(OpenMesh::VertexHandle(0))); + EXPECT_EQ(mesh.normal(OpenMesh::VertexHandle(0)), mesh2.normal(OpenMesh::VertexHandle(0))); + EXPECT_EQ(mesh.normal(OpenMesh::FaceHandle(0)), mesh2.normal(OpenMesh::FaceHandle(0))); +} + } diff --git a/src/Unittests/unittests_read_write_PLY.cc b/src/Unittests/unittests_read_write_PLY.cc index e92a678e..9cb614d7 100644 --- a/src/Unittests/unittests_read_write_PLY.cc +++ b/src/Unittests/unittests_read_write_PLY.cc @@ -81,6 +81,24 @@ TEST_F(OpenMeshReadWritePLY, LoadSimplePLY) { } +/* + * Load a ply ascii file without a newline at the end of the file + * + */ +TEST_F(OpenMeshReadWritePLY, LoadSimplePLYNoEndl) { + + mesh_.clear(); + + bool ok = OpenMesh::IO::read_mesh(mesh_, "sphere840.ply"); + + EXPECT_TRUE(ok) << "Unable to load sphere840.ply"; + + EXPECT_EQ(422u , mesh_.n_vertices()) << "The number of loaded vertices is not correct!"; + EXPECT_EQ(1260u , mesh_.n_edges()) << "The number of loaded edges is not correct!"; + EXPECT_EQ(840u , mesh_.n_faces()) << "The number of loaded faces is not correct!"; + +} + /* * Just load a ply file and set vertex color option before loading */ @@ -129,21 +147,39 @@ TEST_F(OpenMeshReadWritePLY, LoadSimplePLYWithVertexColors) { EXPECT_EQ(18u , mesh_.n_edges()) << "The number of loaded edges is not correct!"; EXPECT_EQ(12u , mesh_.n_faces()) << "The number of loaded faces is not correct!"; - EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(0))[0] ) << "Wrong vertex color at vertex 0 component 0"; +#ifdef TEST_DOUBLE_TRAITS + EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(0))[0] ) << "Wrong vertex color at vertex 0 component 0"; + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(0))[1] ) << "Wrong vertex color at vertex 0 component 1"; + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(0))[2] ) << "Wrong vertex color at vertex 0 component 2"; + + EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(3))[0] ) << "Wrong vertex color at vertex 3 component 0"; + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(3))[1] ) << "Wrong vertex color at vertex 3 component 1"; + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(3))[2] ) << "Wrong vertex color at vertex 3 component 2"; + + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(4))[0] ) << "Wrong vertex color at vertex 4 component 0"; + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(4))[1] ) << "Wrong vertex color at vertex 4 component 1"; + EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(4))[2] ) << "Wrong vertex color at vertex 4 component 2"; + + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(7))[0] ) << "Wrong vertex color at vertex 7 component 0"; + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(7))[1] ) << "Wrong vertex color at vertex 7 component 1"; + EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(7))[2] ) << "Wrong vertex color at vertex 7 component 2"; +#else + EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(0))[0] ) << "Wrong vertex color at vertex 0 component 0"; EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[1] ) << "Wrong vertex color at vertex 0 component 1"; EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[2] ) << "Wrong vertex color at vertex 0 component 2"; - EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(3))[0] ) << "Wrong vertex color at vertex 3 component 0"; - EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[1] ) << "Wrong vertex color at vertex 3 component 1"; - EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[2] ) << "Wrong vertex color at vertex 3 component 2"; + EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(3))[0] ) << "Wrong vertex color at vertex 3 component 0"; + EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[1] ) << "Wrong vertex color at vertex 3 component 1"; + EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[2] ) << "Wrong vertex color at vertex 3 component 2"; - EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[0] ) << "Wrong vertex color at vertex 4 component 0"; + EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[0] ) << "Wrong vertex color at vertex 4 component 0"; EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[1] ) << "Wrong vertex color at vertex 4 component 1"; - EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(4))[2] ) << "Wrong vertex color at vertex 4 component 2"; + EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(4))[2] ) << "Wrong vertex color at vertex 4 component 2"; - EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[0] ) << "Wrong vertex color at vertex 7 component 0"; - EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[1] ) << "Wrong vertex color at vertex 7 component 1"; + EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[0] ) << "Wrong vertex color at vertex 7 component 0"; + EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[1] ) << "Wrong vertex color at vertex 7 component 1"; EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(7))[2] ) << "Wrong vertex color at vertex 7 component 2"; +#endif EXPECT_FALSE(options.vertex_has_normal()) << "Wrong user options are returned!"; EXPECT_FALSE(options.vertex_has_texcoord()) << "Wrong user options are returned!"; @@ -172,21 +208,39 @@ TEST_F(OpenMeshReadWritePLY, LoadPLYFromMeshLabWithVertexColors) { EXPECT_EQ(18u , mesh_.n_edges()) << "The number of loaded edges is not correct!"; EXPECT_EQ(12u , mesh_.n_faces()) << "The number of loaded faces is not correct!"; +#ifdef TEST_DOUBLE_TRAITS + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(0))[0] ) << "Wrong vertex color at vertex 0 component 0"; + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(0))[1] ) << "Wrong vertex color at vertex 0 component 1"; + EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(0))[2] ) << "Wrong vertex color at vertex 0 component 2"; + + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(3))[0] ) << "Wrong vertex color at vertex 3 component 0"; + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(3))[1] ) << "Wrong vertex color at vertex 3 component 1"; + EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(3))[2] ) << "Wrong vertex color at vertex 3 component 2"; + + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(4))[0] ) << "Wrong vertex color at vertex 4 component 0"; + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(4))[1] ) << "Wrong vertex color at vertex 4 component 1"; + EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(4))[2] ) << "Wrong vertex color at vertex 4 component 2"; + + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(7))[0] ) << "Wrong vertex color at vertex 7 component 0"; + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(7))[1] ) << "Wrong vertex color at vertex 7 component 1"; + EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(7))[2] ) << "Wrong vertex color at vertex 7 component 2"; +#else EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[0] ) << "Wrong vertex color at vertex 0 component 0"; EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[1] ) << "Wrong vertex color at vertex 0 component 1"; - EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(0))[2] ) << "Wrong vertex color at vertex 0 component 2"; + EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(0))[2] ) << "Wrong vertex color at vertex 0 component 2"; EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[0] ) << "Wrong vertex color at vertex 3 component 0"; - EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[1] ) << "Wrong vertex color at vertex 3 component 1"; + EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[1] ) << "Wrong vertex color at vertex 3 component 1"; EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(3))[2] ) << "Wrong vertex color at vertex 3 component 2"; - EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[0] ) << "Wrong vertex color at vertex 4 component 0"; + EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[0] ) << "Wrong vertex color at vertex 4 component 0"; EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[1] ) << "Wrong vertex color at vertex 4 component 1"; - EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(4))[2] ) << "Wrong vertex color at vertex 4 component 2"; + EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(4))[2] ) << "Wrong vertex color at vertex 4 component 2"; - EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[0] ) << "Wrong vertex color at vertex 7 component 0"; - EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[1] ) << "Wrong vertex color at vertex 7 component 1"; + EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[0] ) << "Wrong vertex color at vertex 7 component 0"; + EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[1] ) << "Wrong vertex color at vertex 7 component 1"; EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(7))[2] ) << "Wrong vertex color at vertex 7 component 2"; +#endif EXPECT_FALSE(options.vertex_has_normal()) << "Wrong user options are returned!"; EXPECT_FALSE(options.vertex_has_texcoord()) << "Wrong user options are returned!"; @@ -224,21 +278,39 @@ TEST_F(OpenMeshReadWritePLY, WriteAndReadBinaryPLYWithVertexColors) { EXPECT_EQ(18u , mesh_.n_edges()) << "The number of loaded edges is not correct!"; EXPECT_EQ(12u , mesh_.n_faces()) << "The number of loaded faces is not correct!"; +#ifdef TEST_DOUBLE_TRAITS + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(0))[0] ) << "Wrong vertex color at vertex 0 component 0"; + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(0))[1] ) << "Wrong vertex color at vertex 0 component 1"; + EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(0))[2] ) << "Wrong vertex color at vertex 0 component 2"; + + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(3))[0] ) << "Wrong vertex color at vertex 3 component 0"; + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(3))[1] ) << "Wrong vertex color at vertex 3 component 1"; + EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(3))[2] ) << "Wrong vertex color at vertex 3 component 2"; + + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(4))[0] ) << "Wrong vertex color at vertex 4 component 0"; + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(4))[1] ) << "Wrong vertex color at vertex 4 component 1"; + EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(4))[2] ) << "Wrong vertex color at vertex 4 component 2"; + + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(7))[0] ) << "Wrong vertex color at vertex 7 component 0"; + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(7))[1] ) << "Wrong vertex color at vertex 7 component 1"; + EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(7))[2] ) << "Wrong vertex color at vertex 7 component 2"; +#else EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[0] ) << "Wrong vertex color at vertex 0 component 0"; EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[1] ) << "Wrong vertex color at vertex 0 component 1"; - EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(0))[2] ) << "Wrong vertex color at vertex 0 component 2"; + EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(0))[2] ) << "Wrong vertex color at vertex 0 component 2"; EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[0] ) << "Wrong vertex color at vertex 3 component 0"; - EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[1] ) << "Wrong vertex color at vertex 3 component 1"; + EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[1] ) << "Wrong vertex color at vertex 3 component 1"; EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(3))[2] ) << "Wrong vertex color at vertex 3 component 2"; - EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[0] ) << "Wrong vertex color at vertex 4 component 0"; + EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[0] ) << "Wrong vertex color at vertex 4 component 0"; EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[1] ) << "Wrong vertex color at vertex 4 component 1"; - EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(4))[2] ) << "Wrong vertex color at vertex 4 component 2"; + EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(4))[2] ) << "Wrong vertex color at vertex 4 component 2"; - EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[0] ) << "Wrong vertex color at vertex 7 component 0"; - EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[1] ) << "Wrong vertex color at vertex 7 component 1"; + EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[0] ) << "Wrong vertex color at vertex 7 component 0"; + EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[1] ) << "Wrong vertex color at vertex 7 component 1"; EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(7))[2] ) << "Wrong vertex color at vertex 7 component 2"; +#endif EXPECT_FALSE(options.vertex_has_normal()) << "Wrong user options are returned!"; EXPECT_FALSE(options.vertex_has_texcoord()) << "Wrong user options are returned!"; @@ -276,21 +348,39 @@ TEST_F(OpenMeshReadWritePLY, WriteAndReadPLYWithFloatVertexColors) { EXPECT_EQ(18u , mesh_.n_edges()) << "The number of loaded edges is not correct!"; EXPECT_EQ(12u , mesh_.n_faces()) << "The number of loaded faces is not correct!"; +#ifdef TEST_DOUBLE_TRAITS + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(0))[0] ) << "Wrong vertex color at vertex 0 component 0"; + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(0))[1] ) << "Wrong vertex color at vertex 0 component 1"; + EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(0))[2] ) << "Wrong vertex color at vertex 0 component 2"; + + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(3))[0] ) << "Wrong vertex color at vertex 3 component 0"; + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(3))[1] ) << "Wrong vertex color at vertex 3 component 1"; + EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(3))[2] ) << "Wrong vertex color at vertex 3 component 2"; + + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(4))[0] ) << "Wrong vertex color at vertex 4 component 0"; + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(4))[1] ) << "Wrong vertex color at vertex 4 component 1"; + EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(4))[2] ) << "Wrong vertex color at vertex 4 component 2"; + + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(7))[0] ) << "Wrong vertex color at vertex 7 component 0"; + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(7))[1] ) << "Wrong vertex color at vertex 7 component 1"; + EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(7))[2] ) << "Wrong vertex color at vertex 7 component 2"; +#else EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[0] ) << "Wrong vertex color at vertex 0 component 0"; EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[1] ) << "Wrong vertex color at vertex 0 component 1"; - EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(0))[2] ) << "Wrong vertex color at vertex 0 component 2"; + EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(0))[2] ) << "Wrong vertex color at vertex 0 component 2"; EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[0] ) << "Wrong vertex color at vertex 3 component 0"; - EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[1] ) << "Wrong vertex color at vertex 3 component 1"; + EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[1] ) << "Wrong vertex color at vertex 3 component 1"; EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(3))[2] ) << "Wrong vertex color at vertex 3 component 2"; - EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[0] ) << "Wrong vertex color at vertex 4 component 0"; + EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[0] ) << "Wrong vertex color at vertex 4 component 0"; EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[1] ) << "Wrong vertex color at vertex 4 component 1"; - EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(4))[2] ) << "Wrong vertex color at vertex 4 component 2"; + EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(4))[2] ) << "Wrong vertex color at vertex 4 component 2"; - EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[0] ) << "Wrong vertex color at vertex 7 component 0"; - EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[1] ) << "Wrong vertex color at vertex 7 component 1"; + EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[0] ) << "Wrong vertex color at vertex 7 component 0"; + EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[1] ) << "Wrong vertex color at vertex 7 component 1"; EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(7))[2] ) << "Wrong vertex color at vertex 7 component 2"; +#endif EXPECT_FALSE(options.vertex_has_normal()) << "Wrong user options are returned!"; EXPECT_FALSE(options.vertex_has_texcoord()) << "Wrong user options are returned!"; @@ -330,21 +420,39 @@ TEST_F(OpenMeshReadWritePLY, WriteAndReadBinaryPLYWithFloatVertexColors) { EXPECT_EQ(18u , mesh_.n_edges()) << "The number of loaded edges is not correct!"; EXPECT_EQ(12u , mesh_.n_faces()) << "The number of loaded faces is not correct!"; +#ifdef TEST_DOUBLE_TRAITS + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(0))[0] ) << "Wrong vertex color at vertex 0 component 0"; + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(0))[1] ) << "Wrong vertex color at vertex 0 component 1"; + EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(0))[2] ) << "Wrong vertex color at vertex 0 component 2"; + + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(3))[0] ) << "Wrong vertex color at vertex 3 component 0"; + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(3))[1] ) << "Wrong vertex color at vertex 3 component 1"; + EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(3))[2] ) << "Wrong vertex color at vertex 3 component 2"; + + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(4))[0] ) << "Wrong vertex color at vertex 4 component 0"; + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(4))[1] ) << "Wrong vertex color at vertex 4 component 1"; + EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(4))[2] ) << "Wrong vertex color at vertex 4 component 2"; + + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(7))[0] ) << "Wrong vertex color at vertex 7 component 0"; + EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(7))[1] ) << "Wrong vertex color at vertex 7 component 1"; + EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(7))[2] ) << "Wrong vertex color at vertex 7 component 2"; +#else EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[0] ) << "Wrong vertex color at vertex 0 component 0"; EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[1] ) << "Wrong vertex color at vertex 0 component 1"; - EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(0))[2] ) << "Wrong vertex color at vertex 0 component 2"; + EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(0))[2] ) << "Wrong vertex color at vertex 0 component 2"; EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[0] ) << "Wrong vertex color at vertex 3 component 0"; - EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[1] ) << "Wrong vertex color at vertex 3 component 1"; + EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[1] ) << "Wrong vertex color at vertex 3 component 1"; EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(3))[2] ) << "Wrong vertex color at vertex 3 component 2"; - EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[0] ) << "Wrong vertex color at vertex 4 component 0"; + EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[0] ) << "Wrong vertex color at vertex 4 component 0"; EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[1] ) << "Wrong vertex color at vertex 4 component 1"; - EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(4))[2] ) << "Wrong vertex color at vertex 4 component 2"; + EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(4))[2] ) << "Wrong vertex color at vertex 4 component 2"; - EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[0] ) << "Wrong vertex color at vertex 7 component 0"; - EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[1] ) << "Wrong vertex color at vertex 7 component 1"; + EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[0] ) << "Wrong vertex color at vertex 7 component 0"; + EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[1] ) << "Wrong vertex color at vertex 7 component 1"; EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(7))[2] ) << "Wrong vertex color at vertex 7 component 2"; +#endif EXPECT_FALSE(options.vertex_has_normal()) << "Wrong user options are returned!"; EXPECT_FALSE(options.vertex_has_texcoord()) << "Wrong user options are returned!"; @@ -525,6 +633,91 @@ TEST_F(OpenMeshReadWritePLY, LoadSimplePLYWithCustomProps) { } +/* + * Just load a ply with custom properties, binary mode + */ +TEST_F(OpenMeshReadWritePLY, LoadSimplePLYWithCustomPropsBinary) { + + PolyMesh mesh; + + OpenMesh::IO::Options options; + options += OpenMesh::IO::Options::Custom; + options += OpenMesh::IO::Options::Binary; + + bool ok = OpenMesh::IO::read_mesh(mesh, "cube-minimal-custom_props-binary.ply", options); + + EXPECT_TRUE(ok) << "Unable to load cube-minimal-custom_props.ply"; + + EXPECT_EQ(8u , mesh.n_vertices()) << "The number of loaded vertices is not correct!"; + EXPECT_EQ(12u , mesh.n_edges()) << "The number of loaded edges is not correct!"; + EXPECT_EQ(6u , mesh.n_faces()) << "The number of loaded faces is not correct!"; + + OpenMesh::VPropHandleT qualityProp; + OpenMesh::VPropHandleT indexProp; + ASSERT_TRUE(mesh.get_property_handle(qualityProp,"quality")) << "Could not access quality property"; + ASSERT_TRUE(mesh.get_property_handle(indexProp,"index")) << "Could not access index property"; + + //check index property + for (unsigned i = 0; i < mesh.n_vertices(); ++i) + EXPECT_EQ(i ,mesh.property(indexProp,OpenMesh::VertexHandle(i))) << "Vertex index at vertex " << i << " is wrong"; + + //check quality property + EXPECT_EQ(1.f,mesh.property(qualityProp,OpenMesh::VertexHandle(0))) << "Wrong quality value at Vertex 0"; + EXPECT_EQ(0.5f,mesh.property(qualityProp,OpenMesh::VertexHandle(1))) << "Wrong quality value at Vertex 1"; + EXPECT_EQ(0.7f,mesh.property(qualityProp,OpenMesh::VertexHandle(2))) << "Wrong quality value at Vertex 2"; + EXPECT_EQ(1.f,mesh.property(qualityProp,OpenMesh::VertexHandle(3))) << "Wrong quality value at Vertex 3"; + EXPECT_EQ(0.1f,mesh.property(qualityProp,OpenMesh::VertexHandle(4))) << "Wrong quality value at Vertex 4"; + EXPECT_EQ(0.f,mesh.property(qualityProp,OpenMesh::VertexHandle(5))) << "Wrong quality value at Vertex 5"; + EXPECT_EQ(2.f,mesh.property(qualityProp,OpenMesh::VertexHandle(6))) << "Wrong quality value at Vertex 6"; + EXPECT_EQ(5.f,mesh.property(qualityProp,OpenMesh::VertexHandle(7))) << "Wrong quality value at Vertex 7"; + + //check for custom list properties + + OpenMesh::VPropHandleT< std::vector > testValues; + ASSERT_TRUE(mesh.get_property_handle(testValues,"test_values")) << "Could not access texcoords per face"; + + EXPECT_EQ(2u,mesh.property(testValues,OpenMesh::VertexHandle(0)).size()) << "Wrong verctor size"; + + EXPECT_EQ(1,mesh.property(testValues,OpenMesh::VertexHandle(0))[0]) << "Wrong list value at Vertex 0"; + EXPECT_EQ(4,mesh.property(testValues,OpenMesh::VertexHandle(1))[1]) << "Wrong list value at Vertex 1"; + EXPECT_EQ(5,mesh.property(testValues,OpenMesh::VertexHandle(2))[0]) << "Wrong list value at Vertex 2"; + EXPECT_EQ(8,mesh.property(testValues,OpenMesh::VertexHandle(3))[1]) << "Wrong list value at Vertex 3"; + EXPECT_EQ(9,mesh.property(testValues,OpenMesh::VertexHandle(4))[0]) << "Wrong list value at Vertex 4"; + EXPECT_EQ(12,mesh.property(testValues,OpenMesh::VertexHandle(5))[1]) << "Wrong list value at Vertex 5"; + EXPECT_EQ(13,mesh.property(testValues,OpenMesh::VertexHandle(6))[0]) << "Wrong list value at Vertex 6"; + EXPECT_EQ(16,mesh.property(testValues,OpenMesh::VertexHandle(7))[1]) << "Wrong list value at Vertex 7"; + + OpenMesh::FPropHandleT< std::vector > texCoordsPerFace; + ASSERT_TRUE(mesh.get_property_handle(texCoordsPerFace,"texcoords")) << "Could not access texcoords per face"; + + for (Mesh::FaceIter f_iter = mesh.faces_begin(); f_iter != mesh.faces_end(); ++f_iter) + { + EXPECT_EQ(8u, mesh.property(texCoordsPerFace, *f_iter).size()) << "Texcoords per face container has wrong size on face: " << f_iter->idx(); + if (!mesh.property(texCoordsPerFace, *f_iter).empty()) + { + EXPECT_EQ(1.0, mesh.property(texCoordsPerFace, *f_iter)[0]) << "Texcoords wrong on index 0 with face: " << f_iter->idx(); + EXPECT_EQ(1.0, mesh.property(texCoordsPerFace, *f_iter)[1]) << "Texcoords wrong on index 1 with face: " << f_iter->idx(); + EXPECT_EQ(-1.0f, mesh.property(texCoordsPerFace, *f_iter)[2]) << "Texcoords wrong on index 2 with face: " << f_iter->idx(); + EXPECT_EQ(-1.0f, mesh.property(texCoordsPerFace, *f_iter)[3]) << "Texcoords wrong on index 3 with face: " << f_iter->idx(); + EXPECT_EQ(0.0f, mesh.property(texCoordsPerFace, *f_iter)[4]) << "Texcoords wrong on index 4 with face: " << f_iter->idx(); + EXPECT_EQ(0.0f, mesh.property(texCoordsPerFace, *f_iter)[5]) << "Texcoords wrong on index 5 with face: " << f_iter->idx(); + EXPECT_EQ(-0.5f, mesh.property(texCoordsPerFace, *f_iter)[6]) << "Texcoords wrong on index 6 with face: " << f_iter->idx(); + EXPECT_EQ(-0.5f, mesh.property(texCoordsPerFace, *f_iter)[7]) << "Texcoords wrong on index 7 with face: " << f_iter->idx(); + } + + } + + OpenMesh::FPropHandleT< unsigned > faceIndex; + ASSERT_TRUE(mesh.get_property_handle(faceIndex,"faceIndex")) << "Could not access faceIndex per face"; + + EXPECT_EQ(0u,mesh.property(faceIndex,OpenMesh::FaceHandle(0))) << "Wrong index value at FaceHandle 0"; + EXPECT_EQ(1u,mesh.property(faceIndex,OpenMesh::FaceHandle(1))) << "Wrong index value at FaceHandle 1"; + EXPECT_EQ(2u,mesh.property(faceIndex,OpenMesh::FaceHandle(2))) << "Wrong index value at FaceHandle 2"; + EXPECT_EQ(3u,mesh.property(faceIndex,OpenMesh::FaceHandle(3))) << "Wrong index value at FaceHandle 3"; + EXPECT_EQ(4u,mesh.property(faceIndex,OpenMesh::FaceHandle(4))) << "Wrong index value at FaceHandle 4"; + EXPECT_EQ(5u,mesh.property(faceIndex,OpenMesh::FaceHandle(5))) << "Wrong index value at FaceHandle 5"; + +} TEST_F(OpenMeshReadWritePLY, WriteReadSimplePLYWithCustomProps) { @@ -728,4 +921,233 @@ TEST_F(OpenMeshReadWritePLY, LoadSimpleBinaryPLYWithExtraElements) { EXPECT_EQ(12u, mesh_.n_faces()) << "The number of loaded faces is not correct!"; } + +/* +* Ignore a file that does not contain vertices and faces +*/ +TEST_F(OpenMeshReadWritePLY, IgnoreNonMeshPlyFile) { + + mesh_.clear(); + + std::stringstream data; + data << "ply" << "\n"; + data << "format binary_little_endian 1.0" << "\n"; + data << "comment Image data" << "\n"; + data << "element image 0" << "\n"; + data << "property list uint16 uint16 row" << "\n"; + data << "end_header" << "\n"; + + OpenMesh::IO::Options options = OpenMesh::IO::Options::Binary; + + bool ok = OpenMesh::IO::read_mesh(mesh_, data, ".ply", options); + + EXPECT_TRUE(ok) << "This empty file should be readable without an error!"; + + EXPECT_EQ(0u, mesh_.n_vertices()) << "The number of loaded vertices is not correct!"; + EXPECT_EQ(0u, mesh_.n_edges()) << "The number of loaded edges is not correct!"; + EXPECT_EQ(0u, mesh_.n_faces()) << "The number of loaded faces is not correct!"; +} + + +/* +* Ignore a file that does not contain vertices and faces +*/ +TEST_F(OpenMeshReadWritePLY, FailOnUnknownPropertyTypeForLists) { + + mesh_.clear(); + + std::stringstream data; + data << "ply" << "\n"; + data << "format binary_little_endian 1.0" << "\n"; + data << "comment Image data" << "\n"; + data << "element image 0" << "\n"; + data << "property list blibb blubb row" << "\n"; + data << "end_header" << "\n"; + + OpenMesh::IO::Options options = OpenMesh::IO::Options::Binary; + + bool ok = OpenMesh::IO::read_mesh(mesh_, data, ".ply", options); + + EXPECT_FALSE(ok) << "This file should fail to read!"; + + EXPECT_EQ(0u, mesh_.n_vertices()) << "The number of loaded vertices is not correct!"; + EXPECT_EQ(0u, mesh_.n_edges()) << "The number of loaded edges is not correct!"; + EXPECT_EQ(0u, mesh_.n_faces()) << "The number of loaded faces is not correct!"; +} + +/* + * Load an ASCII PLY file of a cube with float RGB face colors + */ +TEST_F(OpenMeshReadWritePLY, LoadSimplePLYWithFaceColors) { + + mesh_.clear(); + + mesh_.request_face_colors(); + + OpenMesh::IO::Options options; + options += OpenMesh::IO::Options::FaceColor; + + bool ok = OpenMesh::IO::read_mesh(mesh_, "cube-minimal-faceColors.ply",options); + + EXPECT_TRUE(ok) << "Unable to load cube-minimal-faceColors.ply"; + + EXPECT_EQ(8u , mesh_.n_vertices()) << "The number of loaded vertices is not correct!"; + EXPECT_EQ(18u, mesh_.n_edges()) << "The number of loaded edges is not correct!"; + EXPECT_EQ(12u, mesh_.n_faces()) << "The number of loaded faces is not correct!"; + +#ifdef TEST_DOUBLE_TRAITS + EXPECT_FLOAT_EQ(107/255.0, mesh_.color(mesh_.face_handle(0))[0] ) << "Wrong face color at face 0"; + EXPECT_FLOAT_EQ(117/255.0, mesh_.color(mesh_.face_handle(0))[1] ) << "Wrong face color at face 0"; + EXPECT_FLOAT_EQ(177/255.0, mesh_.color(mesh_.face_handle(0))[2] ) << "Wrong face color at face 0"; + + EXPECT_FLOAT_EQ(107/255.0, mesh_.color(mesh_.face_handle(3))[0] ) << "Wrong face color at face 3"; + EXPECT_FLOAT_EQ(255/255.0, mesh_.color(mesh_.face_handle(3))[1] ) << "Wrong face color at face 3"; + EXPECT_FLOAT_EQ(135/255.0, mesh_.color(mesh_.face_handle(3))[2] ) << "Wrong face color at face 3"; + + EXPECT_FLOAT_EQ(163/255.0, mesh_.color(mesh_.face_handle(4))[0] ) << "Wrong face color at face 4"; + EXPECT_FLOAT_EQ(107/255.0, mesh_.color(mesh_.face_handle(4))[1] ) << "Wrong face color at face 4"; + EXPECT_FLOAT_EQ(177/255.0, mesh_.color(mesh_.face_handle(4))[2] ) << "Wrong face color at face 4"; + + EXPECT_FLOAT_EQ(255/255.0, mesh_.color(mesh_.face_handle(7))[0] ) << "Wrong face color at face 7"; + EXPECT_FLOAT_EQ(140/255.0, mesh_.color(mesh_.face_handle(7))[1] ) << "Wrong face color at face 7"; + EXPECT_FLOAT_EQ(107/255.0, mesh_.color(mesh_.face_handle(7))[2] ) << "Wrong face color at face 7"; +#else + EXPECT_EQ(107, mesh_.color(mesh_.face_handle(0))[0] ) << "Wrong face color at face 0"; + EXPECT_EQ(117, mesh_.color(mesh_.face_handle(0))[1] ) << "Wrong face color at face 0"; + EXPECT_EQ(177, mesh_.color(mesh_.face_handle(0))[2] ) << "Wrong face color at face 0"; + + EXPECT_EQ(107, mesh_.color(mesh_.face_handle(3))[0] ) << "Wrong face color at face 3"; + EXPECT_EQ(255, mesh_.color(mesh_.face_handle(3))[1] ) << "Wrong face color at face 3"; + EXPECT_EQ(135, mesh_.color(mesh_.face_handle(3))[2] ) << "Wrong face color at face 3"; + + EXPECT_EQ(163, mesh_.color(mesh_.face_handle(4))[0] ) << "Wrong face color at face 4"; + EXPECT_EQ(107, mesh_.color(mesh_.face_handle(4))[1] ) << "Wrong face color at face 4"; + EXPECT_EQ(177, mesh_.color(mesh_.face_handle(4))[2] ) << "Wrong face color at face 4"; + + EXPECT_EQ(255, mesh_.color(mesh_.face_handle(7))[0] ) << "Wrong face color at face 7"; + EXPECT_EQ(140, mesh_.color(mesh_.face_handle(7))[1] ) << "Wrong face color at face 7"; + EXPECT_EQ(107, mesh_.color(mesh_.face_handle(7))[2] ) << "Wrong face color at face 7"; +#endif + + EXPECT_FALSE(options.vertex_has_normal()) << "Wrong user options are returned!"; + EXPECT_FALSE(options.vertex_has_texcoord()) << "Wrong user options are returned!"; + EXPECT_FALSE(options.vertex_has_color()) << "Wrong user options are returned!"; + EXPECT_TRUE(options.face_has_color()) << "Wrong user options are returned!"; + EXPECT_FALSE(options.color_has_alpha()) << "Wrong user options are returned!"; + EXPECT_FALSE(options.is_binary()) << "Wrong user options are returned!"; + + mesh_.release_face_colors(); +} + +/* + * Write and read PLY files with face colors in various formats + */ +TEST_F(OpenMeshReadWritePLY, WriteAndReadPLYWithFaceColors) { + struct Format { + Format(const char* outFileName, OpenMesh::IO::Options options) : + _outFileName(outFileName), + _options(options) + {} + const char* _outFileName; + const OpenMesh::IO::Options _options; + } + formats[] = + { + Format("cube-minimal-faceColors_ascii_uchar.ply", + OpenMesh::IO::Options::Default), + Format("cube-minimal-faceColors_ascii_float.ply", + OpenMesh::IO::Options::ColorFloat), + Format("cube-minimal-faceColors_binary_uchar.ply", + OpenMesh::IO::Options::Binary), + Format("cube-minimal-faceColors_binary_float.ply", + OpenMesh::IO::Options::Binary | OpenMesh::IO::Options::ColorFloat), + // Test writing/reading alpha values (all default 1.0/255), but the test mesh + // Color type has no alpha channel so there's nothing to test below + Format("cube-minimal-faceColors_alpha_ascii_uchar.ply", + OpenMesh::IO::Options::ColorAlpha), + Format("cube-minimal-faceColors_alpha_ascii_float.ply", + OpenMesh::IO::Options::ColorFloat | OpenMesh::IO::Options::ColorAlpha), + Format("cube-minimal-faceColors_alpha_binary_uchar.ply", + OpenMesh::IO::Options::Binary | OpenMesh::IO::Options::ColorAlpha), + Format("cube-minimal-faceColors_alpha_binary_float.ply", + OpenMesh::IO::Options::Binary | OpenMesh::IO::Options::ColorFloat | OpenMesh::IO::Options::ColorAlpha), + }; + + for (size_t i = 0; i < sizeof(formats) / sizeof(Format); ++i) + { + const char* outFileName = formats[i]._outFileName; + + mesh_.clear(); + + mesh_.request_face_colors(); + + OpenMesh::IO::Options options; + options += OpenMesh::IO::Options::FaceColor; + + bool ok = OpenMesh::IO::read_mesh(mesh_, "cube-minimal-faceColors.ply", options); + + EXPECT_TRUE(ok) << "Unable to load cube-minimal-faceColors.ply"; + + options = formats[i]._options; + options += OpenMesh::IO::Options::FaceColor; + ok = OpenMesh::IO::write_mesh(mesh_, outFileName, options); + EXPECT_TRUE(ok) << "Unable to write " << outFileName; + + // Reset for reading: let the reader determine binary/float/etc. + options = OpenMesh::IO::Options::FaceColor; + mesh_.clear(); + ok = OpenMesh::IO::read_mesh(mesh_, outFileName, options); + EXPECT_TRUE(ok) << "Unable to load " << outFileName; + + EXPECT_EQ(8u , mesh_.n_vertices()) << "The number of loaded vertices is not correct: " << outFileName; + EXPECT_EQ(18u, mesh_.n_edges()) << "The number of loaded edges is not correct: " << outFileName; + EXPECT_EQ(12u, mesh_.n_faces()) << "The number of loaded faces is not correct: " << outFileName; + +#ifdef TEST_DOUBLE_TRAITS + EXPECT_FLOAT_EQ(107/255.0, mesh_.color(mesh_.face_handle(0))[0] ) << "Wrong face color at face 0"; + EXPECT_FLOAT_EQ(117/255.0, mesh_.color(mesh_.face_handle(0))[1] ) << "Wrong face color at face 0"; + EXPECT_FLOAT_EQ(177/255.0, mesh_.color(mesh_.face_handle(0))[2] ) << "Wrong face color at face 0"; + + EXPECT_FLOAT_EQ(107/255.0, mesh_.color(mesh_.face_handle(3))[0] ) << "Wrong face color at face 3"; + EXPECT_FLOAT_EQ(255/255.0, mesh_.color(mesh_.face_handle(3))[1] ) << "Wrong face color at face 3"; + EXPECT_FLOAT_EQ(135/255.0, mesh_.color(mesh_.face_handle(3))[2] ) << "Wrong face color at face 3"; + + EXPECT_FLOAT_EQ(163/255.0, mesh_.color(mesh_.face_handle(4))[0] ) << "Wrong face color at face 4"; + EXPECT_FLOAT_EQ(107/255.0, mesh_.color(mesh_.face_handle(4))[1] ) << "Wrong face color at face 4"; + EXPECT_FLOAT_EQ(177/255.0, mesh_.color(mesh_.face_handle(4))[2] ) << "Wrong face color at face 4"; + + EXPECT_FLOAT_EQ(255/255.0, mesh_.color(mesh_.face_handle(7))[0] ) << "Wrong face color at face 7"; + EXPECT_FLOAT_EQ(140/255.0, mesh_.color(mesh_.face_handle(7))[1] ) << "Wrong face color at face 7"; + EXPECT_FLOAT_EQ(107/255.0, mesh_.color(mesh_.face_handle(7))[2] ) << "Wrong face color at face 7"; +#else + EXPECT_EQ(107, mesh_.color(mesh_.face_handle(0))[0] ) << "Wrong face color at face 0"; + EXPECT_EQ(117, mesh_.color(mesh_.face_handle(0))[1] ) << "Wrong face color at face 0"; + EXPECT_EQ(177, mesh_.color(mesh_.face_handle(0))[2] ) << "Wrong face color at face 0"; + + EXPECT_EQ(107, mesh_.color(mesh_.face_handle(3))[0] ) << "Wrong face color at face 3"; + EXPECT_EQ(255, mesh_.color(mesh_.face_handle(3))[1] ) << "Wrong face color at face 3"; + EXPECT_EQ(135, mesh_.color(mesh_.face_handle(3))[2] ) << "Wrong face color at face 3"; + + EXPECT_EQ(163, mesh_.color(mesh_.face_handle(4))[0] ) << "Wrong face color at face 4"; + EXPECT_EQ(107, mesh_.color(mesh_.face_handle(4))[1] ) << "Wrong face color at face 4"; + EXPECT_EQ(177, mesh_.color(mesh_.face_handle(4))[2] ) << "Wrong face color at face 4"; + + EXPECT_EQ(255, mesh_.color(mesh_.face_handle(7))[0] ) << "Wrong face color at face 7"; + EXPECT_EQ(140, mesh_.color(mesh_.face_handle(7))[1] ) << "Wrong face color at face 7"; + EXPECT_EQ(107, mesh_.color(mesh_.face_handle(7))[2] ) << "Wrong face color at face 7"; +#endif + + EXPECT_FALSE(options.vertex_has_normal()) << "Wrong user options are returned: " << outFileName; + EXPECT_FALSE(options.vertex_has_texcoord()) << "Wrong user options are returned: " << outFileName; + EXPECT_FALSE(options.vertex_has_color()) << "Wrong user options are returned: " << outFileName; + EXPECT_TRUE(options.face_has_color()) << "Wrong user options are returned: " << outFileName; + EXPECT_EQ(formats[i]._options.color_is_float(), options.color_is_float()) << + "Wrong user options are returned: " << outFileName; + EXPECT_EQ(formats[i]._options.is_binary(), options.is_binary()) << + "Wrong user options are returned: " << outFileName; + + mesh_.release_face_colors(); + } +} + } diff --git a/src/Unittests/unittests_smart_handles.cc b/src/Unittests/unittests_smart_handles.cc new file mode 100644 index 00000000..6b42b45a --- /dev/null +++ b/src/Unittests/unittests_smart_handles.cc @@ -0,0 +1,566 @@ +#include +#include + +#include + +#include +#include + +namespace { + +class OpenMeshSmartHandles : public OpenMeshBase { + +protected: + + // This function is called before each test is run + virtual void SetUp() { + + mesh_.clear(); + + // Add some vertices + Mesh::VertexHandle vhandle[8]; + vhandle[0] = mesh_.add_vertex(Mesh::Point(-1, -1, 1)); + vhandle[1] = mesh_.add_vertex(Mesh::Point( 1, -1, 1)); + vhandle[2] = mesh_.add_vertex(Mesh::Point( 1, 1, 1)); + vhandle[3] = mesh_.add_vertex(Mesh::Point(-1, 1, 1)); + vhandle[4] = mesh_.add_vertex(Mesh::Point(-1, -1, -1)); + vhandle[5] = mesh_.add_vertex(Mesh::Point( 1, -1, -1)); + vhandle[6] = mesh_.add_vertex(Mesh::Point( 1, 1, -1)); + vhandle[7] = mesh_.add_vertex(Mesh::Point(-1, 1, -1)); + + // Add six faces to form a cube + std::vector face_vhandles; + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[0]); + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[3]); + mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[3]); + mesh_.add_face(face_vhandles); + + //======================= + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[7]); + face_vhandles.push_back(vhandle[6]); + face_vhandles.push_back(vhandle[5]); + mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[7]); + face_vhandles.push_back(vhandle[5]); + face_vhandles.push_back(vhandle[4]); + mesh_.add_face(face_vhandles); + + //======================= + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[0]); + face_vhandles.push_back(vhandle[4]); + mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[4]); + face_vhandles.push_back(vhandle[5]); + mesh_.add_face(face_vhandles); + + //======================= + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[5]); + mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[5]); + face_vhandles.push_back(vhandle[6]); + mesh_.add_face(face_vhandles); + + + //======================= + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[3]); + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[6]); + mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[3]); + face_vhandles.push_back(vhandle[6]); + face_vhandles.push_back(vhandle[7]); + mesh_.add_face(face_vhandles); + + //======================= + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[0]); + face_vhandles.push_back(vhandle[3]); + face_vhandles.push_back(vhandle[7]); + mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[0]); + face_vhandles.push_back(vhandle[7]); + face_vhandles.push_back(vhandle[4]); + mesh_.add_face(face_vhandles); + + + // Test setup: + // + // + // 3 ======== 2 + // / /| + // / / | z + // 0 ======== 1 | | + // | | | | y + // | 7 | 6 | / + // | | / | / + // | |/ |/ + // 4 ======== 5 -------> x + // + + // Check setup + EXPECT_EQ(18u, mesh_.n_edges() ) << "Wrong number of Edges"; + EXPECT_EQ(36u, mesh_.n_halfedges() ) << "Wrong number of HalfEdges"; + EXPECT_EQ(8u, mesh_.n_vertices() ) << "Wrong number of vertices"; + EXPECT_EQ(12u, mesh_.n_faces() ) << "Wrong number of faces"; + } + + // This function is called after all tests are through + virtual void TearDown() { + + // Do some final stuff with the member data here... + + mesh_.clear(); + } + + // Member already defined in OpenMeshBase + //Mesh mesh_; +}; + +/* + * ==================================================================== + * Define tests below + * ==================================================================== + */ + + + +/* Test if navigation operations on smart handles yield the expected element + */ +TEST_F(OpenMeshSmartHandles, SimpleNavigation) +{ + for (auto vh : mesh_.vertices()) + { + EXPECT_EQ(mesh_.halfedge_handle(vh), vh.halfedge()) << "outgoing halfedge of vertex does not match"; + } + + for (auto heh : mesh_.halfedges()) + { + EXPECT_EQ(mesh_.next_halfedge_handle(heh), heh.next()) << "next halfedge of halfedge does not match"; + EXPECT_EQ(mesh_.prev_halfedge_handle(heh), heh.prev()) << "prevt halfedge of halfedge does not match"; + EXPECT_EQ(mesh_.opposite_halfedge_handle(heh), heh.opp()) << "opposite halfedge of halfedge does not match"; + EXPECT_EQ(mesh_.to_vertex_handle(heh), heh.to()) << "to vertex handle of halfedge does not match"; + EXPECT_EQ(mesh_.from_vertex_handle(heh), heh.from()) << "from vertex handle of halfedge does not match"; + EXPECT_EQ(mesh_.face_handle(heh), heh.face()) << "face handle of halfedge does not match"; + } + + for (auto eh : mesh_.edges()) + { + EXPECT_EQ(mesh_.halfedge_handle(eh, 0), eh.h0()) << "halfedge 0 of edge does not match"; + EXPECT_EQ(mesh_.halfedge_handle(eh, 1), eh.h1()) << "halfedge 1 of edge does not match"; + EXPECT_EQ(mesh_.from_vertex_handle(mesh_.halfedge_handle(eh, 0)), eh.v0()) << "first vertex of edge does not match"; + EXPECT_EQ(mesh_.to_vertex_handle (mesh_.halfedge_handle(eh, 0)), eh.v1()) << "second vertex of edge does not match"; + } + + for (auto fh : mesh_.faces()) + { + EXPECT_EQ(mesh_.halfedge_handle(fh), fh.halfedge()) << "halfedge of face does not match"; + } +} + + +/* Test if ranges yield the same elements when using smart handles + */ +TEST_F(OpenMeshSmartHandles, SimpleRanges) +{ + for (auto vh : mesh_.vertices()) + { + { + std::vector handles0; + std::vector handles1; + for (auto h : mesh_.vv_range(vh)) + handles0.push_back(h); + for (auto h : vh.vertices()) + handles1.push_back(h); + EXPECT_EQ(handles0, handles1) << "vertex range of vertex does not match"; + } + { + std::vector handles0; + std::vector handles1; + for (auto h : mesh_.voh_range(vh)) + handles0.push_back(h); + for (auto h : vh.outgoing_halfedges()) + handles1.push_back(h); + EXPECT_EQ(handles0, handles1) << "outgoing halfedge range of vertex does not match"; + } + { + std::vector handles0; + std::vector handles1; + for (auto h : mesh_.vih_range(vh)) + handles0.push_back(h); + for (auto h : vh.incoming_halfedges()) + handles1.push_back(h); + EXPECT_EQ(handles0, handles1) << "incoming halfedge range of vertex does not match"; + } + { + std::vector handles0; + std::vector handles1; + for (auto h : mesh_.ve_range(vh)) + handles0.push_back(h); + for (auto h : vh.edges()) + handles1.push_back(h); + EXPECT_EQ(handles0, handles1) << "edge range of vertex does not match"; + } + { + std::vector handles0; + std::vector handles1; + for (auto h : mesh_.vf_range(vh)) + handles0.push_back(h); + for (auto h : vh.faces()) + handles1.push_back(h); + EXPECT_EQ(handles0, handles1) << "face range of vertex does not match"; + } + } + + for (auto fh : mesh_.faces()) + { + { + std::vector handles0; + std::vector handles1; + for (auto h : mesh_.fv_range(fh)) + handles0.push_back(h); + for (auto h : fh.vertices()) + handles1.push_back(h); + EXPECT_EQ(handles0, handles1) << "vertex range of face does not match"; + } + { + std::vector handles0; + std::vector handles1; + for (auto h : mesh_.fh_range(fh)) + handles0.push_back(h); + for (auto h : fh.halfedges()) + handles1.push_back(h); + EXPECT_EQ(handles0, handles1) << "halfedge range of face does not match"; + } + { + std::vector handles0; + std::vector handles1; + for (auto h : mesh_.fe_range(fh)) + handles0.push_back(h); + for (auto h : fh.edges()) + handles1.push_back(h); + EXPECT_EQ(handles0, handles1) << "edge range of face does not match"; + } + { + std::vector handles0; + std::vector handles1; + for (auto h : mesh_.ff_range(fh)) + handles0.push_back(h); + for (auto h : fh.faces()) + handles1.push_back(h); + EXPECT_EQ(handles0, handles1) << "face range of face does not match"; + } + } +} + +/* Test if ranges yield the same elements when using smart handles + */ +TEST_F(OpenMeshSmartHandles, RangesOfRanges) +{ + for (auto vh : mesh_.vertices()) + { + { + std::vector handles0; + std::vector handles1; + for (auto h : mesh_.vv_range(vh)) + for (auto h2 : mesh_.vv_range(h)) + handles0.push_back(h2); + for (auto h : vh.vertices()) + for (auto h2 : h.vertices()) + handles1.push_back(h2); + EXPECT_EQ(handles0, handles1) << "vertex range of vertex range does not match"; + } + { + std::vector handles0; + std::vector handles1; + for (auto h : mesh_.vv_range(vh)) + for (auto h2 : mesh_.voh_range(h)) + handles0.push_back(h2); + for (auto h : vh.vertices()) + for (auto h2 : h.outgoing_halfedges()) + handles1.push_back(h2); + EXPECT_EQ(handles0, handles1) << "outgoing halfedge range of vertex range does not match"; + } + { + std::vector handles0; + std::vector handles1; + for (auto h : mesh_.vv_range(vh)) + for (auto h2 : mesh_.vih_range(h)) + handles0.push_back(h2); + for (auto h : vh.vertices()) + for (auto h2 : h.incoming_halfedges()) + handles1.push_back(h2); + EXPECT_EQ(handles0, handles1) << "incoming halfedge range of vertex range does not match"; + } + { + std::vector handles0; + std::vector handles1; + for (auto h : mesh_.vv_range(vh)) + for (auto h2 : mesh_.ve_range(h)) + handles0.push_back(h2); + for (auto h : vh.vertices()) + for (auto h2 : h.edges()) + handles1.push_back(h2); + EXPECT_EQ(handles0, handles1) << "edge range of vertex range does not match"; + } + { + std::vector handles0; + std::vector handles1; + for (auto h : mesh_.vv_range(vh)) + for (auto h2 : mesh_.vf_range(h)) + handles0.push_back(h2); + for (auto h : vh.vertices()) + for (auto h2 : h.faces()) + handles1.push_back(h2); + EXPECT_EQ(handles0, handles1) << "face range of vertex range does not match"; + } + { + std::vector handles0; + std::vector handles1; + for (auto h : mesh_.vf_range(vh)) + for (auto h2 : mesh_.fv_range(h)) + handles0.push_back(h2); + for (auto h : vh.faces()) + for (auto h2 : h.vertices()) + handles1.push_back(h2); + EXPECT_EQ(handles0, handles1) << "vertex range of face range does not match"; + } + { + std::vector handles0; + std::vector handles1; + for (auto h : mesh_.vf_range(vh)) + for (auto h2 : mesh_.fh_range(h)) + handles0.push_back(h2); + for (auto h : vh.faces()) + for (auto h2 : h.halfedges()) + handles1.push_back(h2); + EXPECT_EQ(handles0, handles1) << "vertex range of face range does not match"; + } + { + std::vector handles0; + std::vector handles1; + for (auto h : mesh_.vf_range(vh)) + for (auto h2 : mesh_.ff_range(h)) + handles0.push_back(h2); + for (auto h : vh.faces()) + for (auto h2 : h.faces()) + handles1.push_back(h2); + EXPECT_EQ(handles0, handles1) << "vertex range of face range does not match"; + } + } +} + + +/* Test a chain of navigation on a cube + */ +TEST_F(OpenMeshSmartHandles, ComplicatedNavigtaion) +{ + for (auto vh : mesh_.vertices()) + { + EXPECT_EQ(mesh_.next_halfedge_handle( + mesh_.opposite_halfedge_handle( + mesh_.halfedge_handle(vh))), + vh.out().opp().next()); + EXPECT_EQ(mesh_.prev_halfedge_handle( + mesh_.prev_halfedge_handle( + mesh_.opposite_halfedge_handle( + mesh_.next_halfedge_handle( + mesh_.next_halfedge_handle( + mesh_.halfedge_handle(vh)))))), + vh.out().next().next().opp().prev().prev()); + EXPECT_EQ(mesh_.face_handle( + mesh_.opposite_halfedge_handle( + mesh_.halfedge_handle( + mesh_.face_handle( + mesh_.opposite_halfedge_handle( + mesh_.next_halfedge_handle( + mesh_.halfedge_handle(vh))))))), + vh.out().next().opp().face().halfedge().opp().face()); + } +} + + +/* Test performance of smart handles + */ +TEST_F(OpenMeshSmartHandles, Performance) +{ +#if NDEBUG + int n_tests = 10000000; +#else + int n_tests = 300000; +#endif + + auto t_before_old = std::chrono::high_resolution_clock::now(); + + std::vector halfedges0; + for (int i = 0; i < n_tests; ++i) + { + for (auto vh : mesh_.vertices()) + { + auto heh = mesh_.prev_halfedge_handle( + mesh_.prev_halfedge_handle( + mesh_.opposite_halfedge_handle( + mesh_.next_halfedge_handle( + mesh_.next_halfedge_handle( + mesh_.halfedge_handle(vh)))))); + if (i == 0) + halfedges0.push_back(heh); + } + } + + auto t_after_old = std::chrono::high_resolution_clock::now(); + + std::vector halfedges1; + for (int i = 0; i < n_tests; ++i) + { + for (auto vh : mesh_.vertices()) + { + auto heh = vh.out().next().next().opp().prev().prev(); + if (i == 0) + halfedges1.push_back(heh); + } + } + + auto t_after_new = std::chrono::high_resolution_clock::now(); + + std::cout << "Conventional navigation took " << std::chrono::duration_cast(t_after_old-t_before_old).count() << "ms" << std::endl; + std::cout << "SmartHandle navigation took " << std::chrono::duration_cast(t_after_new-t_after_old ).count() << "ms" << std::endl; + + EXPECT_EQ(halfedges0, halfedges1) << "halfedges do not match"; + +} + + +/* Mix old and new api + */ +TEST_F(OpenMeshSmartHandles, MixOldAndNew) +{ + for (OpenMesh::SmartHalfedgeHandle heh : mesh_.halfedges()) + { + heh = mesh_.opposite_halfedge_handle(heh); + EXPECT_TRUE((std::is_same::value)); + EXPECT_TRUE((std::is_same::value)); + EXPECT_TRUE((std::is_same::value)); + } +} + + + +/* comparability + */ +TEST_F(OpenMeshSmartHandles, ComparisionBetweenSmartHandleAndNormalHandles) +{ + OpenMesh::VertexHandle vh(0); + OpenMesh::SmartVertexHandle svh(0, &mesh_); + EXPECT_EQ(vh, svh) << "Vertex handle and smart vertex handle are different"; + + std::vector vertices = mesh_.vertices().to_vector([](OpenMesh::SmartVertexHandle _svh) { return OpenMesh::VertexHandle(_svh); }); + + std::replace(vertices.begin(), vertices.end(), OpenMesh::VertexHandle(0), OpenMesh::VertexHandle(1)); + EXPECT_EQ(vertices[0], OpenMesh::VertexHandle(1)); + + std::vector smart_vertices = mesh_.vertices().to_vector(); + + std::replace(smart_vertices.begin(), smart_vertices.end(), OpenMesh::SmartVertexHandle(0, &mesh_), OpenMesh::SmartVertexHandle(1, &mesh_)); + EXPECT_EQ(smart_vertices[0], OpenMesh::VertexHandle(1)); + EXPECT_EQ(smart_vertices[0], OpenMesh::SmartVertexHandle(1, &mesh_)); + + std::replace(vertices.begin(), vertices.end(), OpenMesh::SmartVertexHandle(1, &mesh_), OpenMesh::SmartVertexHandle(2, &mesh_)); + EXPECT_EQ(vertices[0], OpenMesh::VertexHandle(2)); + +} + +TEST(OpenMeshSmartHandlesNoFixture, AddingFacesPolyMesh) +{ + using MyMesh = OpenMesh::PolyMesh_ArrayKernelT<>; + + MyMesh mesh; + + std::vector vertices; + for (int i = 0; i < 4; ++i) + vertices.push_back(mesh.add_vertex(MyMesh::Point())); + + auto fh = mesh.add_face(vertices); + + for (auto heh : fh.halfedges()) + { + heh = heh.next(); + } +} + +TEST(OpenMeshSmartHandlesNoFixture, AddingFacesTriMesh) +{ + using MyMesh = OpenMesh::TriMesh_ArrayKernelT<>; + + MyMesh mesh; + + std::vector vertices; + for (int i = 0; i < 4; ++i) + vertices.push_back(mesh.add_vertex(MyMesh::Point())); + + auto fh = mesh.add_face(vertices); + + for (auto heh : fh.halfedges()) + { + heh = heh.next(); + } +} + +TEST(OpenMeshSmartHandlesNoFixture, SplitTriMesh) +{ + using MyMesh = OpenMesh::TriMesh_ArrayKernelT<>; + + MyMesh mesh; + + std::vector vertices; + for (int i = 0; i < 3; ++i) + vertices.push_back(mesh.add_vertex(MyMesh::Point())); + + auto fh = mesh.add_face(vertices); + + auto p = (MyMesh::Point()); + + OpenMesh::SmartVertexHandle vh = mesh.split(fh, p); + OpenMesh::SmartEdgeHandle eh = fh.halfedge().edge(); + OpenMesh::SmartVertexHandle vh2 = mesh.split(eh, p); + + EXPECT_NE(vh.idx(), vh2.idx()) << "This was only intended to fix an unused variable warning but cool that it caugth an actual error now"; + +} + + + + + +} diff --git a/src/Unittests/unittests_smart_ranges.cc b/src/Unittests/unittests_smart_ranges.cc new file mode 100644 index 00000000..353e528c --- /dev/null +++ b/src/Unittests/unittests_smart_ranges.cc @@ -0,0 +1,391 @@ +#include +#include + +#include +#include + +#include +#include + +namespace { + +class OpenMeshSmartRanges : public OpenMeshBase { + +protected: + + // This function is called before each test is run + virtual void SetUp() { + + mesh_.clear(); + + // Add some vertices + Mesh::VertexHandle vhandle[8]; + vhandle[0] = mesh_.add_vertex(Mesh::Point(-1, -1, 1)); + vhandle[1] = mesh_.add_vertex(Mesh::Point( 1, -1, 1)); + vhandle[2] = mesh_.add_vertex(Mesh::Point( 1, 1, 1)); + vhandle[3] = mesh_.add_vertex(Mesh::Point(-1, 1, 1)); + vhandle[4] = mesh_.add_vertex(Mesh::Point(-1, -1, -1)); + vhandle[5] = mesh_.add_vertex(Mesh::Point( 1, -1, -1)); + vhandle[6] = mesh_.add_vertex(Mesh::Point( 1, 1, -1)); + vhandle[7] = mesh_.add_vertex(Mesh::Point(-1, 1, -1)); + + // Add six faces to form a cube + std::vector face_vhandles; + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[0]); + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[3]); + mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[3]); + mesh_.add_face(face_vhandles); + + //======================= + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[7]); + face_vhandles.push_back(vhandle[6]); + face_vhandles.push_back(vhandle[5]); + mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[7]); + face_vhandles.push_back(vhandle[5]); + face_vhandles.push_back(vhandle[4]); + mesh_.add_face(face_vhandles); + + //======================= + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[0]); + face_vhandles.push_back(vhandle[4]); + mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[4]); + face_vhandles.push_back(vhandle[5]); + mesh_.add_face(face_vhandles); + + //======================= + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[5]); + mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[5]); + face_vhandles.push_back(vhandle[6]); + mesh_.add_face(face_vhandles); + + + //======================= + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[3]); + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[6]); + mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[3]); + face_vhandles.push_back(vhandle[6]); + face_vhandles.push_back(vhandle[7]); + mesh_.add_face(face_vhandles); + + //======================= + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[0]); + face_vhandles.push_back(vhandle[3]); + face_vhandles.push_back(vhandle[7]); + mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[0]); + face_vhandles.push_back(vhandle[7]); + face_vhandles.push_back(vhandle[4]); + mesh_.add_face(face_vhandles); + + + // Test setup: + // + // + // 3 ======== 2 + // / /| + // / / | z + // 0 ======== 1 | | + // | | | | y + // | 7 | 6 | / + // | | / | / + // | |/ |/ + // 4 ======== 5 -------> x + // + + // Check setup + EXPECT_EQ(18u, mesh_.n_edges() ) << "Wrong number of Edges"; + EXPECT_EQ(36u, mesh_.n_halfedges() ) << "Wrong number of HalfEdges"; + EXPECT_EQ(8u, mesh_.n_vertices() ) << "Wrong number of vertices"; + EXPECT_EQ(12u, mesh_.n_faces() ) << "Wrong number of faces"; + } + + // This function is called after all tests are through + virtual void TearDown() { + + // Do some final stuff with the member data here... + + mesh_.clear(); + } + + // Member already defined in OpenMeshBase + //Mesh mesh_; +}; + +/* + * ==================================================================== + * Define tests below + * ==================================================================== + */ + + +template +struct F +{ + unsigned int operator()(HandleT ) { return 1; } +}; + +/* Test if smart ranges work + */ +TEST_F(OpenMeshSmartRanges, Sum) +{ + auto one = [](OpenMesh::VertexHandle ) { return 1u; }; + EXPECT_EQ(mesh_.vertices().sum(one), mesh_.n_vertices()); + EXPECT_EQ(mesh_.vertices().sum(F()), mesh_.n_vertices()); + EXPECT_EQ(mesh_.halfedges().sum(F()), mesh_.n_halfedges()); + EXPECT_EQ(mesh_.edges().sum(F()), mesh_.n_edges()); + EXPECT_EQ(mesh_.faces().sum(F()), mesh_.n_faces()); + + for (auto vh : mesh_.vertices()) + EXPECT_EQ(vh.vertices().sum(F()), mesh_.valence(vh)); + for (auto vh : mesh_.vertices()) + EXPECT_EQ(vh.faces().sum(F()), mesh_.valence(vh)); + for (auto vh : mesh_.vertices()) + EXPECT_EQ(vh.outgoing_halfedges().sum(F()), mesh_.valence(vh)); + for (auto vh : mesh_.vertices()) + EXPECT_EQ(vh.incoming_halfedges().sum(F()), mesh_.valence(vh)); + + for (auto fh : mesh_.faces()) + EXPECT_EQ(fh.vertices().sum(F()), mesh_.valence(fh)); + for (auto fh : mesh_.faces()) + EXPECT_EQ(fh.halfedges().sum(F()), mesh_.valence(fh)); + for (auto fh : mesh_.faces()) + EXPECT_EQ(fh.edges().sum(F()), mesh_.valence(fh)); + for (auto fh : mesh_.faces()) + EXPECT_EQ(fh.faces().sum(F()), 3u); +} + + +/* Test if Property Manager can be used in smart ranges + */ +TEST_F(OpenMeshSmartRanges, PropertyManagerAsFunctor) +{ + OpenMesh::VProp myPos(mesh_); + for (auto vh : mesh_.vertices()) + myPos(vh) = mesh_.point(vh); + + Mesh::Point cog(0,0,0); + for (auto vh : mesh_.vertices()) + cog += mesh_.point(vh); + cog /= mesh_.n_vertices(); + + auto cog2 = mesh_.vertices().avg(myPos); + + EXPECT_LT(norm(cog - cog2), 0.00001) << "Computed center of gravities are significantly different."; +} + +/* Test to vector + */ +TEST_F(OpenMeshSmartRanges, ToVector) +{ + OpenMesh::HProp uvs(mesh_); + + for (auto heh : mesh_.halfedges()) + uvs(heh) = OpenMesh::Vec2d(heh.idx(), (heh.idx() * 13)%7); + + for (auto fh : mesh_.faces()) + { + auto tri_uvs = fh.halfedges().to_vector(uvs); + auto heh_handles = fh.halfedges().to_vector(); + for (auto heh : heh_handles) + heh.next(); + } + + auto vertex_vec = mesh_.vertices().to_vector(); + for (auto vh : vertex_vec) + vh.out(); +} + +/* Test to array + */ +TEST_F(OpenMeshSmartRanges, ToArray) +{ + OpenMesh::HProp uvs(mesh_); + + for (auto heh : mesh_.halfedges()) + uvs(heh) = OpenMesh::Vec2d(heh.idx(), (heh.idx() * 13)%7); + + for (auto fh : mesh_.faces()) + { + fh.halfedges().to_array<3>(uvs); + fh.halfedges().to_array<3>(); + } +} + + +/* Test bounding box + */ +TEST_F(OpenMeshSmartRanges, BoundingBox) +{ + // The custom vecs OpenMesh are tested with here do not implement a min or max function. + // Thus we convert here. + OpenMesh::VProp myPos(mesh_); + for (auto vh : mesh_.vertices()) + for (size_t i = 0; i < 3; ++i) + myPos(vh)[i] = mesh_.point(vh)[i]; + + auto bb_min = mesh_.vertices().min(myPos); + auto bb_max = mesh_.vertices().max(myPos); + mesh_.vertices().minmax(myPos); + + EXPECT_LT(norm(bb_min - OpenMesh::Vec3f(-1,-1,-1)), 0.000001) << "Bounding box minimum seems off"; + EXPECT_LT(norm(bb_max - OpenMesh::Vec3f( 1, 1, 1)), 0.000001) << "Bounding box maximum seems off"; + + + auto uvs = OpenMesh::makeTemporaryProperty(mesh_); + for (auto heh : mesh_.halfedges()) + uvs(heh) = OpenMesh::Vec2d(heh.idx(), (heh.idx() * 13)%7); + + for (auto fh : mesh_.faces()) + { + fh.halfedges().min(uvs); + fh.halfedges().max(uvs); + } +} + + +/* Test for each + */ +TEST_F(OpenMeshSmartRanges, ForEach) +{ + std::vector vec; + auto f = [&vec](OpenMesh::VertexHandle vh) { vec.push_back(vh.idx()); }; + + mesh_.vertices().for_each(f); + + ASSERT_EQ(vec.size(), mesh_.n_vertices()) << "vec has wrong size"; + for (size_t i = 0; i < vec.size(); ++i) + EXPECT_EQ(vec[i], i) << "wrong index in vector"; +} + + +/* Test filter + */ +TEST_F(OpenMeshSmartRanges, Filtered) +{ + using VH = OpenMesh::VertexHandle; + using FH = OpenMesh::FaceHandle; + + auto is_even = [](VH vh) { return vh.idx() % 2 == 0; }; + auto is_odd = [](VH vh) { return vh.idx() % 2 == 1; }; + auto is_divisible_by_3 = [](VH vh) { return vh.idx() % 3 == 0; }; + auto to_id = [](VH vh) { return vh.idx(); }; + + auto even_vertices = mesh_.vertices().filtered(is_even).to_vector(to_id); + EXPECT_EQ(even_vertices.size(), 4); + EXPECT_EQ(even_vertices[0], 0); + EXPECT_EQ(even_vertices[1], 2); + EXPECT_EQ(even_vertices[2], 4); + EXPECT_EQ(even_vertices[3], 6); + + auto odd_vertices = mesh_.vertices().filtered(is_odd).to_vector(to_id); + EXPECT_EQ(odd_vertices.size(), 4); + EXPECT_EQ(odd_vertices[0], 1); + EXPECT_EQ(odd_vertices[1], 3); + EXPECT_EQ(odd_vertices[2], 5); + EXPECT_EQ(odd_vertices[3], 7); + + auto even_3_vertices = mesh_.vertices().filtered(is_even).filtered(is_divisible_by_3).to_vector(to_id); + EXPECT_EQ(even_3_vertices.size(), 2); + EXPECT_EQ(even_3_vertices[0], 0); + EXPECT_EQ(even_3_vertices[1], 6); + + auto odd_3_vertices = mesh_.vertices().filtered(is_odd).filtered(is_divisible_by_3).to_vector(to_id); + EXPECT_EQ(odd_3_vertices.size(), 1); + EXPECT_EQ(odd_3_vertices[0], 3); + + + // create a vector of vertices in the order they are visited when iterating over face vertices, but every vertex only once + std::vector vertices; + OpenMesh::VProp to_be_processed(true, mesh_); + auto store_vertex = [&](VH vh) { to_be_processed(vh) = false; vertices.push_back(vh); }; + + for (auto fh : mesh_.faces()) + fh.vertices().filtered(to_be_processed).for_each(store_vertex); + + EXPECT_EQ(vertices.size(), mesh_.n_vertices()) << " number of visited vertices not correct"; + EXPECT_TRUE(mesh_.vertices().all_of([&](VH vh) { return !to_be_processed(vh); })) << "did not visit all vertices"; + + { + OpenMesh::FProp to_be_visited(true, mesh_); + int visited_faces_in_main_loop = 0; + int visited_faces_in_sub_loop = 0; + for (auto fh : mesh_.faces().filtered(to_be_visited)) + { + to_be_visited(fh) = false; + ++visited_faces_in_main_loop; + for (auto neighbor : fh.faces().filtered(to_be_visited)) + { + to_be_visited(neighbor) = false; + ++visited_faces_in_sub_loop; + } + } + + EXPECT_LT(visited_faces_in_main_loop, mesh_.n_faces()) << "Visted more faces than expected"; + EXPECT_TRUE(mesh_.faces().all_of([&](FH fh) { return !to_be_visited(fh); })) << "did not visit all faces"; + EXPECT_EQ(visited_faces_in_main_loop + visited_faces_in_sub_loop, mesh_.n_faces()) << "Did not visited all faces exactly once"; + } + + { + OpenMesh::FProp to_be_visited(true, mesh_); + const auto& to_be_visited_const_ref = to_be_visited; + int visited_faces_in_main_loop = 0; + int visited_faces_in_sub_loop = 0; + for (auto fh : mesh_.faces().filtered(to_be_visited_const_ref)) + { + to_be_visited(fh) = false; + ++visited_faces_in_main_loop; + for (auto neighbor : fh.faces().filtered(to_be_visited_const_ref)) + { + to_be_visited(neighbor) = false; + ++visited_faces_in_sub_loop; + } + } + + EXPECT_LT(visited_faces_in_main_loop, mesh_.n_faces()) << "Visted more faces than expected"; + EXPECT_TRUE(mesh_.faces().all_of([&](FH fh) { return !to_be_visited(fh); })) << "did not visit all faces"; + EXPECT_EQ(visited_faces_in_main_loop + visited_faces_in_sub_loop, mesh_.n_faces()) << "Did not visited all faces exactly once"; + } + +} + + + +} diff --git a/src/Unittests/unittests_smarttagger.cc b/src/Unittests/unittests_smarttagger.cc new file mode 100644 index 00000000..112fbf74 --- /dev/null +++ b/src/Unittests/unittests_smarttagger.cc @@ -0,0 +1,252 @@ +#include +#include +#include +#include + +namespace { + +class OpenMeshSmartTagger : public OpenMeshBase { + + protected: + + // This function is called before each test is run + virtual void SetUp() { + + // Do some initial stuff with the member data here... + } + + // This function is called after all tests are through + virtual void TearDown() { + + // Do some final stuff with the member data here... + } + + // Member already defined in OpenMeshBase + //Mesh mesh_; +}; + +/* + * ==================================================================== + * Define tests below + * ==================================================================== + */ + +/* Checks SmartTagger on vertices + */ +TEST_F(OpenMeshSmartTagger, SmartTaggerVertices) { + + mesh_.clear(); + + // Add some vertices + Mesh::VertexHandle vhandle[7]; + + vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 1, 0)); + vhandle[1] = mesh_.add_vertex(Mesh::Point(1, 0, 0)); + vhandle[2] = mesh_.add_vertex(Mesh::Point(2, 1, 0)); + vhandle[3] = mesh_.add_vertex(Mesh::Point(0,-1, 0)); + vhandle[4] = mesh_.add_vertex(Mesh::Point(2,-1, 0)); + vhandle[5] = mesh_.add_vertex(Mesh::Point(3, 0, 0)); + + + // Add two faces + std::vector face_vhandles; + + face_vhandles.push_back(vhandle[0]); + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[2]); + mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[3]); + face_vhandles.push_back(vhandle[4]); + mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[0]); + face_vhandles.push_back(vhandle[3]); + face_vhandles.push_back(vhandle[1]); + mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[4]); + mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[5]); + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[4]); + mesh_.add_face(face_vhandles); + + /* Test setup: + 0 ==== 2 + |\ /|\ + | \ / | \ + | 1 | 5 + | / \ | / + |/ \|/ + 3 ==== 4 + + */ + + + OpenMesh::SmartTaggerVT< Mesh > tagger(mesh_); + + + EXPECT_FALSE( tagger.is_tagged(vhandle[0] ) ) << "Vertex should be untagged after init!"; + EXPECT_FALSE( tagger.is_tagged(vhandle[1] ) ) << "Vertex should be untagged after init!"; + EXPECT_FALSE( tagger.is_tagged(vhandle[2] ) ) << "Vertex should be untagged after init!"; + EXPECT_FALSE( tagger.is_tagged(vhandle[3] ) ) << "Vertex should be untagged after init!"; + EXPECT_FALSE( tagger.is_tagged(vhandle[4] ) ) << "Vertex should be untagged after init!"; + EXPECT_FALSE( tagger.is_tagged(vhandle[5] ) ) << "Vertex should be untagged after init!"; + + // Reset tagged flag on all vertices + tagger.untag_all(); + + EXPECT_FALSE( tagger.is_tagged(vhandle[0] ) ) << "Vertex should be untagged after first untag_all!"; + EXPECT_FALSE( tagger.is_tagged(vhandle[1] ) ) << "Vertex should be untagged after first untag_all!"; + EXPECT_FALSE( tagger.is_tagged(vhandle[2] ) ) << "Vertex should be untagged after first untag_all!"; + EXPECT_FALSE( tagger.is_tagged(vhandle[3] ) ) << "Vertex should be untagged after first untag_all!"; + EXPECT_FALSE( tagger.is_tagged(vhandle[4] ) ) << "Vertex should be untagged after first untag_all!"; + EXPECT_FALSE( tagger.is_tagged(vhandle[5] ) ) << "Vertex should be untagged after first untag_all!"; + + + // Set tagged: + tagger.set_tag(vhandle[2]); + tagger.set_tag(vhandle[4]); + + EXPECT_FALSE( tagger.is_tagged(vhandle[0] ) ) << "Vertex should be untagged!"; + EXPECT_FALSE( tagger.is_tagged(vhandle[1] ) ) << "Vertex should be untagged!"; + EXPECT_TRUE( tagger.is_tagged(vhandle[2] ) ) << "Vertex should be tagged!"; + EXPECT_FALSE( tagger.is_tagged(vhandle[3] ) ) << "Vertex should be untagged!"; + EXPECT_TRUE( tagger.is_tagged(vhandle[4] ) ) << "Vertex should be tagged!"; + EXPECT_FALSE( tagger.is_tagged(vhandle[5] ) ) << "Vertex should be untagged!"; + + // Reset tagged flag on all vertices + tagger.untag_all(); + + EXPECT_FALSE( tagger.is_tagged(vhandle[0] ) ) << "Vertex should be untagged after second untag_all!"; + EXPECT_FALSE( tagger.is_tagged(vhandle[1] ) ) << "Vertex should be untagged after second untag_all!"; + EXPECT_FALSE( tagger.is_tagged(vhandle[2] ) ) << "Vertex should be untagged after second untag_all!"; + EXPECT_FALSE( tagger.is_tagged(vhandle[3] ) ) << "Vertex should be untagged after second untag_all!"; + EXPECT_FALSE( tagger.is_tagged(vhandle[4] ) ) << "Vertex should be untagged after second untag_all!"; + EXPECT_FALSE( tagger.is_tagged(vhandle[5] ) ) << "Vertex should be untagged after second untag_all!"; + +} + +/* Checks SmartTagger on vertices + */ +TEST_F(OpenMeshSmartTagger, SmartTaggerFaces) { + + mesh_.clear(); + + // Add some vertices + Mesh::VertexHandle vhandle[7]; + + vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 1, 0)); + vhandle[1] = mesh_.add_vertex(Mesh::Point(1, 0, 0)); + vhandle[2] = mesh_.add_vertex(Mesh::Point(2, 1, 0)); + vhandle[3] = mesh_.add_vertex(Mesh::Point(0,-1, 0)); + vhandle[4] = mesh_.add_vertex(Mesh::Point(2,-1, 0)); + vhandle[5] = mesh_.add_vertex(Mesh::Point(3, 0, 0)); + + + // Add two faces + std::vector face_vhandles; + + face_vhandles.push_back(vhandle[0]); + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[2]); + Mesh::FaceHandle fh1 = mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[3]); + face_vhandles.push_back(vhandle[4]); + Mesh::FaceHandle fh2 = mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[0]); + face_vhandles.push_back(vhandle[3]); + face_vhandles.push_back(vhandle[1]); + Mesh::FaceHandle fh3 = mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[4]); + Mesh::FaceHandle fh4 = mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[5]); + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[4]); + Mesh::FaceHandle fh5 = mesh_.add_face(face_vhandles); + + /* Test setup: + 0 ==== 2 + |\ /|\ + | \ / | \ + | 1 | 5 + | / \ | / + |/ \|/ + 3 ==== 4 + + */ + + + OpenMesh::SmartTaggerFT< Mesh > tagger(mesh_); + + + EXPECT_FALSE( tagger.is_tagged( fh1 ) ) << "Face should be untagged after init!"; + EXPECT_FALSE( tagger.is_tagged( fh2 ) ) << "Face should be untagged after init!"; + EXPECT_FALSE( tagger.is_tagged( fh3 ) ) << "Face should be untagged after init!"; + EXPECT_FALSE( tagger.is_tagged( fh4 ) ) << "Face should be untagged after init!"; + EXPECT_FALSE( tagger.is_tagged( fh5 ) ) << "Face should be untagged after init!"; + + + // Reset tagged flag on all vertices + tagger.untag_all(); + + EXPECT_FALSE( tagger.is_tagged( fh1 ) ) << "Face should be untagged after first untag_all!"; + EXPECT_FALSE( tagger.is_tagged( fh2 ) ) << "Face should be untagged after first untag_all!"; + EXPECT_FALSE( tagger.is_tagged( fh3 ) ) << "Face should be untagged after first untag_all!"; + EXPECT_FALSE( tagger.is_tagged( fh4 ) ) << "Face should be untagged after first untag_all!"; + EXPECT_FALSE( tagger.is_tagged( fh5 ) ) << "Face should be untagged after first untag_all!"; + + + + // Set tagged: + tagger.set_tag(fh3); + tagger.set_tag(fh5); + + + EXPECT_FALSE( tagger.is_tagged(fh1 ) ) << "Face should be untagged!"; + EXPECT_FALSE( tagger.is_tagged(fh2 ) ) << "Face should be untagged!"; + EXPECT_TRUE( tagger.is_tagged(fh3 ) ) << "Face should be tagged!"; + EXPECT_FALSE( tagger.is_tagged(fh4 ) ) << "Face should be tagged!"; + EXPECT_TRUE( tagger.is_tagged(fh5 ) ) << "Face should be tagged!"; + + + // Reset tagged flag on all vertices + tagger.untag_all(); + + EXPECT_FALSE( tagger.is_tagged( fh1 ) ) << "Face should be untagged after second untag_all!"; + EXPECT_FALSE( tagger.is_tagged( fh2 ) ) << "Face should be untagged after second untag_all!"; + EXPECT_FALSE( tagger.is_tagged( fh3 ) ) << "Face should be untagged after second untag_all!"; + EXPECT_FALSE( tagger.is_tagged( fh4 ) ) << "Face should be untagged after second untag_all!"; + EXPECT_FALSE( tagger.is_tagged( fh5 ) ) << "Face should be untagged after second untag_all!"; + +} + +} diff --git a/src/Unittests/unittests_split_edge_copy.cc b/src/Unittests/unittests_split_edge_copy.cc index 4dd2088d..60b93581 100644 --- a/src/Unittests/unittests_split_edge_copy.cc +++ b/src/Unittests/unittests_split_edge_copy.cc @@ -91,13 +91,15 @@ TEST_F(OpenMeshSplitEdgeCopyTriangleMesh, SplitEdgeCopyTriangleMesh) { //set internal property mesh_.status(eh).set_tagged(true); - // split face with new vertex - mesh_.split_edge_copy(eh, vhandle[3]); + // split edge with new vertex + mesh_.split_copy(eh, vhandle[3]); // Check setup Mesh::EdgeHandle eh0 = mesh_.edge_handle( mesh_.next_halfedge_handle( mesh_.halfedge_handle(eh, 1) ) ); EXPECT_EQ(999, mesh_.property(eprop_int, eh0)) << "Different Property value"; EXPECT_TRUE(mesh_.status(eh0).tagged()) << "Different internal property value"; + + EXPECT_EQ(3u, mesh_.valence(fh)) << "Face of TriMesh has valence other than 3"; } /* splits an edge that has a property in a poly mesh with split_edge_copy @@ -125,7 +127,7 @@ TEST_F(OpenMeshSplitEdgeCopyPolyMesh, SplitEdgeCopyPolymesh) { face_vhandles.push_back(vhandle[2]); face_vhandles.push_back(vhandle[3]); - PolyMesh::FaceHandle fh = mesh_.add_face(face_vhandles); + mesh_.add_face(face_vhandles); PolyMesh::EdgeHandle eh = *mesh_.edges_begin(); // Test setup: @@ -152,4 +154,102 @@ TEST_F(OpenMeshSplitEdgeCopyPolyMesh, SplitEdgeCopyPolymesh) { EXPECT_EQ(999, mesh_.property(eprop_int, eh0)) << "Different Property value"; EXPECT_TRUE(mesh_.status(eh0).tagged()) << "Different internal property value"; } + + +/* splits an edge in a triangle mesh that has a face property with split_edge_copy + * the property should be copied to the new edge + */ +TEST_F(OpenMeshSplitEdgeCopyTriangleMesh, SplitEdgeCopyFacePropertiesTriangleMesh) { + + mesh_.clear(); + mesh_.request_edge_status(); + mesh_.request_face_status(); + + static_assert(std::is_same::value, "Mesh is not a triangle mesh"); + + // Add some vertices + Mesh::VertexHandle vhandle[4]; + + vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 0, 0)); + vhandle[1] = mesh_.add_vertex(Mesh::Point(0, 1, 0)); + vhandle[2] = mesh_.add_vertex(Mesh::Point(1, 1, 0)); + vhandle[3] = mesh_.add_vertex(Mesh::Point(1, 0, 0)); + + Mesh::VertexHandle inner_vertex = mesh_.add_vertex(Mesh::Point(0.5, 0.5, 0)); + Mesh::VertexHandle boundary_vertex = mesh_.add_vertex(Mesh::Point(0.0, 0.5, 0)); + + // Add two faces + std::vector face_vhandles; + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[0]); + + Mesh::FaceHandle fh0 = mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[0]); + face_vhandles.push_back(vhandle[3]); + + Mesh::FaceHandle fh1 = mesh_.add_face(face_vhandles); + + Mesh::EdgeHandle inner_edge = Mesh::EdgeHandle(2); + + EXPECT_EQ(mesh_.n_faces(), 2u); + + // Test setup: + // 1 --- 2 + // | / | + // | / | + // | / | + // 0 --- 3 + + // set property + OpenMesh::FPropHandleT fprop_int; + mesh_.add_property(fprop_int); + mesh_.property(fprop_int, fh0) = 13; + mesh_.property(fprop_int, fh1) = 17; + //set internal property + mesh_.status(fh0).set_tagged(true); + + // 2 to 4 split + mesh_.split_copy(inner_edge, inner_vertex); + + EXPECT_EQ(mesh_.n_faces(), 4u); + + for (auto fh : mesh_.faces()) + { + EXPECT_EQ(3u, mesh_.valence(fh)); + } + + // Check setup + Mesh::HalfedgeHandle heh21 = mesh_.find_halfedge(vhandle[2], vhandle[1]); + Mesh::HalfedgeHandle heh10 = mesh_.find_halfedge(vhandle[1], vhandle[0]); + Mesh::HalfedgeHandle heh03 = mesh_.find_halfedge(vhandle[0], vhandle[3]); + Mesh::HalfedgeHandle heh32 = mesh_.find_halfedge(vhandle[3], vhandle[2]); + + EXPECT_EQ(13, mesh_.property(fprop_int, mesh_.face_handle(heh21))) << "Different Property value"; + EXPECT_EQ(13, mesh_.property(fprop_int, mesh_.face_handle(heh10))) << "Different Property value"; + EXPECT_EQ(17, mesh_.property(fprop_int, mesh_.face_handle(heh03))) << "Different Property value"; + EXPECT_EQ(17, mesh_.property(fprop_int, mesh_.face_handle(heh32))) << "Different Property value"; + EXPECT_TRUE(mesh_.status(mesh_.face_handle(heh21)).tagged()) << "Different internal property value"; + EXPECT_TRUE(mesh_.status(mesh_.face_handle(heh10)).tagged()) << "Different internal property value"; + EXPECT_FALSE(mesh_.status(mesh_.face_handle(heh03)).tagged()) << "Different internal property value"; + EXPECT_FALSE(mesh_.status(mesh_.face_handle(heh32)).tagged()) << "Different internal property value"; + + // also test boundary split + Mesh::EdgeHandle boundary_edge = mesh_.edge_handle(heh10); + + // 1 to 2 split + mesh_.split_copy(boundary_edge, boundary_vertex); + + Mesh::HalfedgeHandle heh1b = mesh_.find_halfedge(vhandle[1], boundary_vertex); + Mesh::HalfedgeHandle hehb0 = mesh_.find_halfedge(boundary_vertex, vhandle[0]); + + EXPECT_EQ(13, mesh_.property(fprop_int, mesh_.face_handle(heh1b))) << "Different Property value"; + EXPECT_EQ(13, mesh_.property(fprop_int, mesh_.face_handle(hehb0))) << "Different Property value"; + EXPECT_TRUE(mesh_.status(mesh_.face_handle(heh1b)).tagged()) << "Different internal property value"; + EXPECT_TRUE(mesh_.status(mesh_.face_handle(hehb0)).tagged()) << "Different internal property value"; +} + } diff --git a/src/Unittests/unittests_subdivider_uniform.cc b/src/Unittests/unittests_subdivider_uniform.cc index b10cc734..835c89cf 100644 --- a/src/Unittests/unittests_subdivider_uniform.cc +++ b/src/Unittests/unittests_subdivider_uniform.cc @@ -1,7 +1,9 @@ #include #include +#include #include +#include #include #include @@ -147,6 +149,371 @@ TEST_F(OpenMeshSubdividerUniform_Triangle, Subdivider_Sqrt3) { EXPECT_EQ(216u, mesh_.n_faces() ) << "Wrong number of faces after subdivision with sqrt3"; } + +TEST_F(OpenMeshSubdividerUniform_Triangle, Subdivider_Sqrt3_delete_vertex) { + + for (bool collect_garbage : { false, true }) + { + mesh_.clear(); + + // Request status flags to use delete and garbage collection + mesh_.request_vertex_status(); + mesh_.request_halfedge_status(); + mesh_.request_edge_status(); + mesh_.request_face_status(); + + // Add some vertices + Mesh::VertexHandle vhandle[9]; + + vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 0, 0)); + vhandle[1] = mesh_.add_vertex(Mesh::Point(0, 1, 0)); + vhandle[2] = mesh_.add_vertex(Mesh::Point(0, 2, 0)); + vhandle[3] = mesh_.add_vertex(Mesh::Point(1, 0, 0)); + vhandle[4] = mesh_.add_vertex(Mesh::Point(1, 1, 0)); + vhandle[5] = mesh_.add_vertex(Mesh::Point(1, 2, 0)); + vhandle[6] = mesh_.add_vertex(Mesh::Point(2, 0, 0)); + vhandle[7] = mesh_.add_vertex(Mesh::Point(2, 1, 0)); + vhandle[8] = mesh_.add_vertex(Mesh::Point(2, 2, 0)); + + // Add eight faces + std::vector face_vhandles; + + face_vhandles.push_back(vhandle[0]); + face_vhandles.push_back(vhandle[4]); + face_vhandles.push_back(vhandle[3]); + + mesh_.add_face(face_vhandles); + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[0]); + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[4]); + + mesh_.add_face(face_vhandles); + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[4]); + + mesh_.add_face(face_vhandles); + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[5]); + face_vhandles.push_back(vhandle[4]); + + mesh_.add_face(face_vhandles); + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[3]); + face_vhandles.push_back(vhandle[7]); + face_vhandles.push_back(vhandle[6]); + + mesh_.add_face(face_vhandles); + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[3]); + face_vhandles.push_back(vhandle[4]); + face_vhandles.push_back(vhandle[7]); + + mesh_.add_face(face_vhandles); + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[4]); + face_vhandles.push_back(vhandle[8]); + face_vhandles.push_back(vhandle[7]); + + mesh_.add_face(face_vhandles); + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[4]); + face_vhandles.push_back(vhandle[5]); + face_vhandles.push_back(vhandle[8]); + + mesh_.add_face(face_vhandles); + + // Test setup: + // 6 === 7 === 8 + // | / | / | + // | / | / | + // | / | / | + // 3 === 4 === 5 + // | / | \ | + // | / | \ | + // | / | \ | + // 0 === 1 === 2 + + // Delete one vertex + mesh_.delete_vertex(vhandle[1]); + // Check setup + if (collect_garbage) + { + mesh_.garbage_collection(); + EXPECT_EQ(8u, mesh_.n_vertices() ) << "Wrong number of vertices"; + EXPECT_EQ(6u, mesh_.n_faces() ) << "Wrong number of faces"; + } + else + { + EXPECT_EQ(9u, mesh_.n_vertices() ) << "Wrong number of vertices"; + EXPECT_EQ(8u, mesh_.n_faces() ) << "Wrong number of faces"; + } + + + // Initialize subdivider + OpenMesh::Subdivider::Uniform::Sqrt3T sqrt3; + + + // Execute 3 subdivision steps + sqrt3.attach(mesh_); + sqrt3( 3 ); + sqrt3.detach(); + + if (!collect_garbage) + mesh_.garbage_collection(); // if we did not collect garbage before, do so now + + // Check setup + EXPECT_EQ(94u, mesh_.n_vertices() ) << "Wrong number of vertices after subdivision with sqrt3"; + EXPECT_EQ(162u, mesh_.n_faces() ) << "Wrong number of faces after subdivision with sqrt3"; + } +} + + +TEST_F(OpenMeshSubdividerUniform_Triangle, Subdivider_Loop) { + mesh_.clear(); + + // Add some vertices + Mesh::VertexHandle vhandle[9]; + + vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 0, 0)); + vhandle[1] = mesh_.add_vertex(Mesh::Point(0, 1, 0)); + vhandle[2] = mesh_.add_vertex(Mesh::Point(0, 2, 0)); + vhandle[3] = mesh_.add_vertex(Mesh::Point(1, 0, 0)); + vhandle[4] = mesh_.add_vertex(Mesh::Point(1, 1, 0)); + vhandle[5] = mesh_.add_vertex(Mesh::Point(1, 2, 0)); + vhandle[6] = mesh_.add_vertex(Mesh::Point(2, 0, 0)); + vhandle[7] = mesh_.add_vertex(Mesh::Point(2, 1, 0)); + vhandle[8] = mesh_.add_vertex(Mesh::Point(2, 2, 0)); + + // Add eight faces + std::vector face_vhandles; + + face_vhandles.push_back(vhandle[0]); + face_vhandles.push_back(vhandle[4]); + face_vhandles.push_back(vhandle[3]); + + mesh_.add_face(face_vhandles); + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[0]); + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[4]); + + mesh_.add_face(face_vhandles); + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[4]); + + mesh_.add_face(face_vhandles); + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[5]); + face_vhandles.push_back(vhandle[4]); + + mesh_.add_face(face_vhandles); + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[3]); + face_vhandles.push_back(vhandle[7]); + face_vhandles.push_back(vhandle[6]); + + mesh_.add_face(face_vhandles); + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[3]); + face_vhandles.push_back(vhandle[4]); + face_vhandles.push_back(vhandle[7]); + + mesh_.add_face(face_vhandles); + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[4]); + face_vhandles.push_back(vhandle[8]); + face_vhandles.push_back(vhandle[7]); + + mesh_.add_face(face_vhandles); + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[4]); + face_vhandles.push_back(vhandle[5]); + face_vhandles.push_back(vhandle[8]); + + mesh_.add_face(face_vhandles); + + // Test setup: + // 6 === 7 === 8 + // | / | / | + // | / | / | + // | / | / | + // 3 === 4 === 5 + // | / | \ | + // | / | \ | + // | / | \ | + // 0 === 1 === 2 + + // Initialize subdivider + OpenMesh::Subdivider::Uniform::LoopT loop; + + // Check setup + EXPECT_EQ(9u, mesh_.n_vertices() ) << "Wrong number of vertices"; + EXPECT_EQ(8u, mesh_.n_faces() ) << "Wrong number of faces"; + + // Execute 3 subdivision steps + loop.attach(mesh_); + loop( 3 ); + loop.detach(); + + // Check setup + EXPECT_EQ(289u, mesh_.n_vertices() ) << "Wrong number of vertices after subdivision with loop"; + EXPECT_EQ(512u, mesh_.n_faces() ) << "Wrong number of faces after subdivision with loop"; +} + + + +TEST_F(OpenMeshSubdividerUniform_Triangle, Subdivider_Loop_delete_vertex) { + + for (bool collect_garbage : { false, true }) + { + mesh_.clear(); + + // Request status flags to use delete and garbage collection + mesh_.request_vertex_status(); + mesh_.request_halfedge_status(); + mesh_.request_edge_status(); + mesh_.request_face_status(); + + // Add some vertices + Mesh::VertexHandle vhandle[9]; + + vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 0, 0)); + vhandle[1] = mesh_.add_vertex(Mesh::Point(0, 1, 0)); + vhandle[2] = mesh_.add_vertex(Mesh::Point(0, 2, 0)); + vhandle[3] = mesh_.add_vertex(Mesh::Point(1, 0, 0)); + vhandle[4] = mesh_.add_vertex(Mesh::Point(1, 1, 0)); + vhandle[5] = mesh_.add_vertex(Mesh::Point(1, 2, 0)); + vhandle[6] = mesh_.add_vertex(Mesh::Point(2, 0, 0)); + vhandle[7] = mesh_.add_vertex(Mesh::Point(2, 1, 0)); + vhandle[8] = mesh_.add_vertex(Mesh::Point(2, 2, 0)); + + // Add eight faces + std::vector face_vhandles; + + face_vhandles.push_back(vhandle[0]); + face_vhandles.push_back(vhandle[4]); + face_vhandles.push_back(vhandle[3]); + + mesh_.add_face(face_vhandles); + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[0]); + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[4]); + + mesh_.add_face(face_vhandles); + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[4]); + + mesh_.add_face(face_vhandles); + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[5]); + face_vhandles.push_back(vhandle[4]); + + mesh_.add_face(face_vhandles); + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[3]); + face_vhandles.push_back(vhandle[7]); + face_vhandles.push_back(vhandle[6]); + + mesh_.add_face(face_vhandles); + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[3]); + face_vhandles.push_back(vhandle[4]); + face_vhandles.push_back(vhandle[7]); + + mesh_.add_face(face_vhandles); + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[4]); + face_vhandles.push_back(vhandle[8]); + face_vhandles.push_back(vhandle[7]); + + mesh_.add_face(face_vhandles); + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[4]); + face_vhandles.push_back(vhandle[5]); + face_vhandles.push_back(vhandle[8]); + + mesh_.add_face(face_vhandles); + + // Test setup: + // 6 === 7 === 8 + // | / | / | + // | / | / | + // | / | / | + // 3 === 4 === 5 + // | / | \ | + // | / | \ | + // | / | \ | + // 0 === 1 === 2 + + // Delete one vertex + mesh_.delete_vertex(vhandle[1]); + if (collect_garbage) + { + mesh_.garbage_collection(); + // Check setup + EXPECT_EQ(8u, mesh_.n_vertices() ) << "Wrong number of vertices"; + EXPECT_EQ(6u, mesh_.n_faces() ) << "Wrong number of faces"; + } + else + { + // Check setup + EXPECT_EQ(9u, mesh_.n_vertices() ) << "Wrong number of vertices"; + EXPECT_EQ(8u, mesh_.n_faces() ) << "Wrong number of faces"; + } + + // Initialize subdivider + OpenMesh::Subdivider::Uniform::LoopT loop; + + + // Execute 3 subdivision steps + loop.attach(mesh_); + loop( 3 ); + loop.detach(); + + if (!collect_garbage) + mesh_.garbage_collection(); // if we did not collect garbage before, do so now + + // Check setup + EXPECT_EQ(225u, mesh_.n_vertices() ) << "Wrong number of vertices after subdivision with loop"; + EXPECT_EQ(384u, mesh_.n_faces() ) << "Wrong number of faces after subdivision with loop"; + + } +} + + + /* * ==================================================================== * Define tests below @@ -232,6 +599,108 @@ TEST_F(OpenMeshSubdividerUniform_Poly, Subdivider_CatmullClark) { EXPECT_EQ(256u, mesh_.n_faces() ) << "Wrong number of faces after subdivision with catmull clark"; } + +TEST_F(OpenMeshSubdividerUniform_Poly, Subdivider_CatmullClark_delete_vertex) { + + for (bool collect_garbage : { false, true }) + { + mesh_.clear(); + + // Request status flags to use delete and garbage collection + mesh_.request_vertex_status(); + mesh_.request_halfedge_status(); + mesh_.request_edge_status(); + mesh_.request_face_status(); + + // Add some vertices + Mesh::VertexHandle vhandle[9]; + + vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 0, 0)); + vhandle[1] = mesh_.add_vertex(Mesh::Point(0, 1, 0)); + vhandle[2] = mesh_.add_vertex(Mesh::Point(0, 2, 0)); + vhandle[3] = mesh_.add_vertex(Mesh::Point(1, 0, 0)); + vhandle[4] = mesh_.add_vertex(Mesh::Point(1, 1, 0)); + vhandle[5] = mesh_.add_vertex(Mesh::Point(1, 2, 0)); + vhandle[6] = mesh_.add_vertex(Mesh::Point(2, 0, 0)); + vhandle[7] = mesh_.add_vertex(Mesh::Point(2, 1, 0)); + vhandle[8] = mesh_.add_vertex(Mesh::Point(2, 2, 0)); + + // Add four faces + std::vector face_vhandles; + + face_vhandles.push_back(vhandle[0]); + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[4]); + face_vhandles.push_back(vhandle[3]); + + mesh_.add_face(face_vhandles); + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[5]); + face_vhandles.push_back(vhandle[4]); + + mesh_.add_face(face_vhandles); + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[4]); + face_vhandles.push_back(vhandle[5]); + face_vhandles.push_back(vhandle[8]); + face_vhandles.push_back(vhandle[7]); + + mesh_.add_face(face_vhandles); + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[3]); + face_vhandles.push_back(vhandle[4]); + face_vhandles.push_back(vhandle[7]); + face_vhandles.push_back(vhandle[6]); + + mesh_.add_face(face_vhandles); + + // Test setup: + // 6 === 7 === 8 + // | | | + // | | | + // | | | + // 3 === 4 === 5 + // | | | + // | | | + // | | | + // 0 === 1 === 2 + + + mesh_.delete_vertex(vhandle[1]); + // Check setup + if (collect_garbage) + { + mesh_.garbage_collection(); + EXPECT_EQ(6u, mesh_.n_vertices() ) << "Wrong number of vertices"; + EXPECT_EQ(2u, mesh_.n_faces() ) << "Wrong number of faces"; + } + else + { + EXPECT_EQ(9u, mesh_.n_vertices() ) << "Wrong number of vertices"; + EXPECT_EQ(4u, mesh_.n_faces() ) << "Wrong number of faces"; + } + + // Initialize subdivider + OpenMesh::Subdivider::Uniform::CatmullClarkT catmull; + + // Execute 3 subdivision steps + catmull.attach(mesh_); + catmull( 3 ); + catmull.detach(); + + if (!collect_garbage) + mesh_.garbage_collection(); // if we did not collect garbage before, do so now + + EXPECT_EQ(153u, mesh_.n_vertices() ) << "Wrong number of vertices after subdivision with catmull clark"; + EXPECT_EQ(128u, mesh_.n_faces() ) << "Wrong number of faces after subdivision with catmull clark"; + } +} + /* Adds a cube to a polymesh */ TEST_F(OpenMeshSubdividerUniform_Poly, Midpoint) { @@ -329,4 +798,364 @@ TEST_F(OpenMeshSubdividerUniform_Poly, Midpoint) { EXPECT_EQ(26u, mesh_.n_faces()) << "Wrong number of faces"; } + +TEST_F(OpenMeshSubdividerUniform_Poly, Midpoint_delete_vertex) { + + for (bool collect_garbage : { false, true }) + { + mesh_.clear(); + + // Request status flags to use delete and garbage collection + mesh_.request_vertex_status(); + mesh_.request_halfedge_status(); + mesh_.request_edge_status(); + mesh_.request_face_status(); + + // Add some vertices + Mesh::VertexHandle vhandle[8]; + vhandle[0] = mesh_.add_vertex(PolyMesh::Point(-1, -1, 1)); + vhandle[1] = mesh_.add_vertex(PolyMesh::Point( 1, -1, 1)); + vhandle[2] = mesh_.add_vertex(PolyMesh::Point( 1, 1, 1)); + vhandle[3] = mesh_.add_vertex(PolyMesh::Point(-1, 1, 1)); + vhandle[4] = mesh_.add_vertex(PolyMesh::Point(-1, -1, -1)); + vhandle[5] = mesh_.add_vertex(PolyMesh::Point( 1, -1, -1)); + vhandle[6] = mesh_.add_vertex(PolyMesh::Point( 1, 1, -1)); + vhandle[7] = mesh_.add_vertex(PolyMesh::Point(-1, 1, -1)); + + // Add six faces to form a cube + std::vector face_vhandles; + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[0]); + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[3]); + mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[7]); + face_vhandles.push_back(vhandle[6]); + face_vhandles.push_back(vhandle[5]); + face_vhandles.push_back(vhandle[4]); + mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[0]); + face_vhandles.push_back(vhandle[4]); + face_vhandles.push_back(vhandle[5]); + mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[5]); + face_vhandles.push_back(vhandle[6]); + mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[3]); + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[6]); + face_vhandles.push_back(vhandle[7]); + mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[0]); + face_vhandles.push_back(vhandle[3]); + face_vhandles.push_back(vhandle[7]); + face_vhandles.push_back(vhandle[4]); + mesh_.add_face(face_vhandles); + + + // Test setup: + // + // + // 3 ======== 2 + // / /| + // / / | z + // 0 ======== 1 | | + // | | | | y + // | 7 | 6 | / + // | | / | / + // | |/ |/ + // 4 ======== 5 -------> x + // + + mesh_.delete_vertex(vhandle[1]); + // Check setup + if (collect_garbage) + { + mesh_.garbage_collection(); + EXPECT_EQ(9u, mesh_.n_edges()) << "Wrong number of Edges"; + EXPECT_EQ(18u, mesh_.n_halfedges()) << "Wrong number of HalfEdges"; + EXPECT_EQ(7u, mesh_.n_vertices()) << "Wrong number of vertices"; + EXPECT_EQ(3u, mesh_.n_faces()) << "Wrong number of faces"; + } + else + { + EXPECT_EQ(12u, mesh_.n_edges()) << "Wrong number of Edges"; + EXPECT_EQ(24u, mesh_.n_halfedges()) << "Wrong number of HalfEdges"; + EXPECT_EQ(8u, mesh_.n_vertices()) << "Wrong number of vertices"; + EXPECT_EQ(6u, mesh_.n_faces()) << "Wrong number of faces"; + } + + // Check setup + + // Initialize subdivider + OpenMesh::Subdivider::Uniform::MidpointT midpoint; + + // Execute 2 subdivision steps + midpoint.attach(mesh_); + midpoint(2); + midpoint.detach(); + + if (!collect_garbage) + mesh_.garbage_collection(); // if we did not collect garbage before, do so now + + // Check Result + EXPECT_EQ(15u, mesh_.n_edges()) << "Wrong number of Edges"; + EXPECT_EQ(30u, mesh_.n_halfedges()) << "Wrong number of HalfEdges"; + EXPECT_EQ(12u, mesh_.n_vertices()) << "Wrong number of vertices"; + EXPECT_EQ(4u, mesh_.n_faces()) << "Wrong number of faces"; + } +} + + + +TEST_F(OpenMeshSubdividerUniform_Triangle, Modified_Butterfly) { + mesh_.clear(); + + // Add some vertices + Mesh::VertexHandle vhandle[9]; + + vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 0, 0)); + vhandle[1] = mesh_.add_vertex(Mesh::Point(0, 1, 0)); + vhandle[2] = mesh_.add_vertex(Mesh::Point(0, 2, 0)); + vhandle[3] = mesh_.add_vertex(Mesh::Point(1, 0, 0)); + vhandle[4] = mesh_.add_vertex(Mesh::Point(1, 1, 0)); + vhandle[5] = mesh_.add_vertex(Mesh::Point(1, 2, 0)); + vhandle[6] = mesh_.add_vertex(Mesh::Point(2, 0, 0)); + vhandle[7] = mesh_.add_vertex(Mesh::Point(2, 1, 0)); + vhandle[8] = mesh_.add_vertex(Mesh::Point(2, 2, 0)); + + // Add eight faces + std::vector face_vhandles; + + face_vhandles.push_back(vhandle[0]); + face_vhandles.push_back(vhandle[4]); + face_vhandles.push_back(vhandle[3]); + + mesh_.add_face(face_vhandles); + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[0]); + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[4]); + + mesh_.add_face(face_vhandles); + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[4]); + + mesh_.add_face(face_vhandles); + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[5]); + face_vhandles.push_back(vhandle[4]); + + mesh_.add_face(face_vhandles); + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[3]); + face_vhandles.push_back(vhandle[7]); + face_vhandles.push_back(vhandle[6]); + + mesh_.add_face(face_vhandles); + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[3]); + face_vhandles.push_back(vhandle[4]); + face_vhandles.push_back(vhandle[7]); + + mesh_.add_face(face_vhandles); + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[4]); + face_vhandles.push_back(vhandle[8]); + face_vhandles.push_back(vhandle[7]); + + mesh_.add_face(face_vhandles); + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[4]); + face_vhandles.push_back(vhandle[5]); + face_vhandles.push_back(vhandle[8]); + + mesh_.add_face(face_vhandles); + + // Test setup: + // 6 === 7 === 8 + // | / | / | + // | / | / | + // | / | / | + // 3 === 4 === 5 + // | / | \ | + // | / | \ | + // | / | \ | + // 0 === 1 === 2 + + // Initialize subdivider + OpenMesh::Subdivider::Uniform::ModifiedButterflyT butter; + + // Check setup + EXPECT_EQ(9u, mesh_.n_vertices() ) << "Wrong number of vertices"; + EXPECT_EQ(8u, mesh_.n_faces() ) << "Wrong number of faces"; + + // Execute 3 subdivision steps + butter.attach(mesh_); + butter( 3 ); + butter.detach(); + + // Check setup + EXPECT_EQ(289u, mesh_.n_vertices() ) << "Wrong number of vertices after subdivision with loop"; + EXPECT_EQ(512u, mesh_.n_faces() ) << "Wrong number of faces after subdivision with loop"; +} + + + +TEST_F(OpenMeshSubdividerUniform_Triangle, Modified_Butterfly_delete_vertex) { + + for (bool collect_garbage : { false, true }) + { + mesh_.clear(); + + // Request status flags to use delete and garbage collection + mesh_.request_vertex_status(); + mesh_.request_halfedge_status(); + mesh_.request_edge_status(); + mesh_.request_face_status(); + + // Add some vertices + Mesh::VertexHandle vhandle[9]; + + vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 0, 0)); + vhandle[1] = mesh_.add_vertex(Mesh::Point(0, 1, 0)); + vhandle[2] = mesh_.add_vertex(Mesh::Point(0, 2, 0)); + vhandle[3] = mesh_.add_vertex(Mesh::Point(1, 0, 0)); + vhandle[4] = mesh_.add_vertex(Mesh::Point(1, 1, 0)); + vhandle[5] = mesh_.add_vertex(Mesh::Point(1, 2, 0)); + vhandle[6] = mesh_.add_vertex(Mesh::Point(2, 0, 0)); + vhandle[7] = mesh_.add_vertex(Mesh::Point(2, 1, 0)); + vhandle[8] = mesh_.add_vertex(Mesh::Point(2, 2, 0)); + + // Add eight faces + std::vector face_vhandles; + + face_vhandles.push_back(vhandle[0]); + face_vhandles.push_back(vhandle[4]); + face_vhandles.push_back(vhandle[3]); + + mesh_.add_face(face_vhandles); + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[0]); + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[4]); + + mesh_.add_face(face_vhandles); + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[4]); + + mesh_.add_face(face_vhandles); + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[5]); + face_vhandles.push_back(vhandle[4]); + + mesh_.add_face(face_vhandles); + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[3]); + face_vhandles.push_back(vhandle[7]); + face_vhandles.push_back(vhandle[6]); + + mesh_.add_face(face_vhandles); + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[3]); + face_vhandles.push_back(vhandle[4]); + face_vhandles.push_back(vhandle[7]); + + mesh_.add_face(face_vhandles); + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[4]); + face_vhandles.push_back(vhandle[8]); + face_vhandles.push_back(vhandle[7]); + + mesh_.add_face(face_vhandles); + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[4]); + face_vhandles.push_back(vhandle[5]); + face_vhandles.push_back(vhandle[8]); + + mesh_.add_face(face_vhandles); + + // Test setup: + // 6 === 7 === 8 + // | / | / | + // | / | / | + // | / | / | + // 3 === 4 === 5 + // | / | \ | + // | / | \ | + // | / | \ | + // 0 === 1 === 2 + + + // Delete one vertex + mesh_.delete_vertex(vhandle[1]); + // Check setup + if (collect_garbage) + { + mesh_.garbage_collection(); + EXPECT_EQ(8u, mesh_.n_vertices() ) << "Wrong number of vertices"; + EXPECT_EQ(6u, mesh_.n_faces() ) << "Wrong number of faces"; + } + else + { + EXPECT_EQ(9u, mesh_.n_vertices() ) << "Wrong number of vertices"; + EXPECT_EQ(8u, mesh_.n_faces() ) << "Wrong number of faces"; + } + + // Initialize subdivider + OpenMesh::Subdivider::Uniform::ModifiedButterflyT butter; + + + // Execute 3 subdivision steps + butter.attach(mesh_); + butter( 3 ); + butter.detach(); + + if (!collect_garbage) + mesh_.garbage_collection(); // if we did not collect garbage before, do so now + + // Check setup + EXPECT_EQ(225u, mesh_.n_vertices() ) << "Wrong number of vertices after subdivision with butter"; + EXPECT_EQ(384u, mesh_.n_faces() ) << "Wrong number of faces after subdivision with butter"; + } +} + + + + } diff --git a/src/Unittests/unittests_trimesh_collapse.cc b/src/Unittests/unittests_trimesh_collapse.cc index fea9307a..99640d8e 100644 --- a/src/Unittests/unittests_trimesh_collapse.cc +++ b/src/Unittests/unittests_trimesh_collapse.cc @@ -741,5 +741,4 @@ TEST_F(OpenMeshCollapse, DeletedStatus) { EXPECT_FALSE(mesh_.status(mesh_.opposite_halfedge_handle(bottom_right)).deleted()) << "Halfedge from vertex 5 to vertex 3 is deleted"; } - } diff --git a/src/Unittests/unittests_trimesh_iterators.cc b/src/Unittests/unittests_trimesh_iterators.cc index 913c40f3..d4e36f21 100644 --- a/src/Unittests/unittests_trimesh_iterators.cc +++ b/src/Unittests/unittests_trimesh_iterators.cc @@ -773,7 +773,7 @@ TEST_F(OpenMeshIterators, FaceIterEmptyMeshOneDeletedFace) { vhandle[1] = mesh_.add_vertex(Mesh::Point(0, 1, 0)); vhandle[2] = mesh_.add_vertex(Mesh::Point(1, 1, 0)); - // Add two faces + // Add one faces std::vector face_vhandles; face_vhandles.push_back(vhandle[2]); @@ -841,4 +841,162 @@ TEST_F(OpenMeshIterators, FaceIterEmptyMeshOneDeletedFace) { mesh_.release_face_status(); } + + + +/* + * Test range iterators + */ +TEST_F(OpenMeshIterators, RangeIterators) { + + mesh_.clear(); + + // request delete_face capability + mesh_.request_vertex_status(); + mesh_.request_edge_status(); + mesh_.request_halfedge_status(); + mesh_.request_face_status(); + + // Add some vertices + Mesh::VertexHandle vhandle[4]; + + vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 0, 0)); + vhandle[1] = mesh_.add_vertex(Mesh::Point(0, 1, 0)); + vhandle[2] = mesh_.add_vertex(Mesh::Point(1, 1, 0)); + vhandle[3] = mesh_.add_vertex(Mesh::Point(1, 0, 0)); + + // Add two faces + std::vector face_vhandles; + + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[0]); + mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[0]); + face_vhandles.push_back(vhandle[3]); + face_vhandles.push_back(vhandle[2]); + Mesh::FaceHandle fh = mesh_.add_face(face_vhandles); + + // Delete one face + mesh_.delete_face(fh); + + // Test setup (right face deleted) + // 1 --- 2 + // | / | + // | / | + // | / | + // 0 --- 3 + + + // ====== Faces ====== + + int count_faces_iter = 0; + for (auto f_it = mesh_.faces_begin(); f_it != mesh_.faces_end(); ++f_it) + ++count_faces_iter; + EXPECT_EQ(2, count_faces_iter) << "Wrong number of visited faces."; + + int count_faces_skipping_iter = 0; + for (auto f_it = mesh_.faces_sbegin(); f_it != mesh_.faces_end(); ++f_it) + ++count_faces_skipping_iter; + EXPECT_EQ(1, count_faces_skipping_iter) << "Wrong number of visited faces."; + + int count_faces_range = 0; + for (auto fh : mesh_.faces()) + if (fh.is_valid()) // not actually necessary but fixes unused variable warning + ++count_faces_range; + EXPECT_EQ(1, count_faces_range) << "Wrong number of visited faces."; + + int count_faces_range_all = 0; + for (auto fh : mesh_.all_faces()) + if (fh.is_valid()) // not actually necessary but fixes unused variable warning + ++count_faces_range_all; + EXPECT_EQ(2, count_faces_range_all) << "Wrong number of visited faces."; + + + // ====== Edges ====== + + int count_edges_iter = 0; + for (auto e_it = mesh_.edges_begin(); e_it != mesh_.edges_end(); ++e_it) + ++count_edges_iter; + EXPECT_EQ(5, count_edges_iter) << "Wrong number of visited edges."; + + int count_edges_skipping_iter = 0; + for (auto e_it = mesh_.edges_sbegin(); e_it != mesh_.edges_end(); ++e_it) + ++count_edges_skipping_iter; + EXPECT_EQ(3, count_edges_skipping_iter) << "Wrong number of visited edges."; + + int count_edges_range = 0; + for (auto eh : mesh_.edges()) + if (eh.is_valid()) // not actually necessary but fixes unused variable warning + ++count_edges_range; + EXPECT_EQ(3, count_edges_range) << "Wrong number of visited edges."; + + int count_edges_range_all = 0; + for (auto eh : mesh_.all_edges()) + if (eh.is_valid()) // not actually necessary but fixes unused variable warning + ++count_edges_range_all; + EXPECT_EQ(5, count_edges_range_all) << "Wrong number of visited edges."; + + + // ====== Halfedges ====== + + int count_halfedges_iter = 0; + for (auto h_it = mesh_.halfedges_begin(); h_it != mesh_.halfedges_end(); ++h_it) + ++count_halfedges_iter; + EXPECT_EQ(10, count_halfedges_iter) << "Wrong number of visited halfedges."; + + int count_halfedges_skipping_iter = 0; + for (auto h_it = mesh_.halfedges_sbegin(); h_it != mesh_.halfedges_end(); ++h_it) + ++count_halfedges_skipping_iter; + EXPECT_EQ(6, count_halfedges_skipping_iter) << "Wrong number of visited halfedges."; + + int count_halfedges_range = 0; + for (auto heh : mesh_.halfedges()) + if (heh.is_valid()) // not actually necessary but fixes unused variable warning + ++count_halfedges_range; + EXPECT_EQ(6, count_halfedges_range) << "Wrong number of visited halfedges."; + + int count_halfedges_range_all = 0; + for (auto heh : mesh_.all_halfedges()) + if (heh.is_valid()) // not actually necessary but fixes unused variable warning + ++count_halfedges_range_all; + EXPECT_EQ(10, count_halfedges_range_all) << "Wrong number of visited halfedges."; + + + // ====== Vertices ====== + + int count_vertices_iter = 0; + for (auto v_it = mesh_.vertices_begin(); v_it != mesh_.vertices_end(); ++v_it) + ++count_vertices_iter; + EXPECT_EQ(4, count_vertices_iter) << "Wrong number of visited vertices."; + + int count_vertices_skipping_iter = 0; + for (auto v_it = mesh_.vertices_sbegin(); v_it != mesh_.vertices_end(); ++v_it) + ++count_vertices_skipping_iter; + EXPECT_EQ(3, count_vertices_skipping_iter) << "Wrong number of visited vertices."; + + int count_vertices_range = 0; + for (auto vh : mesh_.vertices()) + if (vh.is_valid()) // not actually necessary but fixes unused variable warning + ++count_vertices_range; + EXPECT_EQ(3, count_vertices_range) << "Wrong number of visited vertices."; + + int count_vertices_range_all = 0; + for (auto vh : mesh_.all_vertices()) + if (vh.is_valid()) // not actually necessary but fixes unused variable warning + ++count_vertices_range_all; + EXPECT_EQ(4, count_vertices_range_all) << "Wrong number of visited vertices."; + + + mesh_.release_vertex_status(); + mesh_.release_edge_status(); + mesh_.release_halfedge_status(); + mesh_.release_face_status(); + +} + + + } diff --git a/src/Unittests/unittests_trimesh_others.cc b/src/Unittests/unittests_trimesh_others.cc index a9aaebd1..5a771021 100644 --- a/src/Unittests/unittests_trimesh_others.cc +++ b/src/Unittests/unittests_trimesh_others.cc @@ -164,7 +164,8 @@ TEST_F(OpenMeshOthers, CalcDihedralAngre ) { EXPECT_EQ( 0.0 , mesh_.calc_dihedral_angle(eh) ) << "Wrong Dihedral angle!" << std::endl; // Modify point - Mesh::Point tmp = ( Mesh::Point(0.0, 0.0, -1.0) + Mesh::Point(1.0, 1.0, -1.0) ) * static_cast(0.5); + Mesh::Point tmp = ( Mesh::Point(0.0, 0.0, -1.0) + Mesh::Point(1.0, 1.0, -1.0) ) + * static_cast::value_type>(0.5); mesh_.point(vhandle[2]) = tmp; double difference = fabs( 1.36944 - mesh_.calc_dihedral_angle(eh) ); diff --git a/src/Unittests/unittests_tutorials.cc b/src/Unittests/unittests_tutorials.cc index 552fa614..b227d166 100644 --- a/src/Unittests/unittests_tutorials.cc +++ b/src/Unittests/unittests_tutorials.cc @@ -1,5 +1,6 @@ #include +#include #include #include #include @@ -197,7 +198,7 @@ public: public: // construct with a given mesh - SmootherT(Mesh& _mesh) + explicit SmootherT(Mesh& _mesh) : mesh_(_mesh) { mesh_.add_property( cog_ ); @@ -445,39 +446,34 @@ TEST_F(OpenMeshTutorials, using_iterators_and_circulators) { TEST_F(OpenMeshTutorials, using_custom_properties) { MyMesh mesh; - bool ok = OpenMesh::IO::read_mesh(mesh, "output.off"); - EXPECT_TRUE(ok) << "Cannot read mesh from file 'output.off'"; + bool ok = OpenMesh::IO::read_mesh(mesh, "cube_noisy.off"); + EXPECT_TRUE(ok) << "Cannot read mesh from file 'cube_noisy.off'"; - // this vertex property stores the computed centers of gravity - OpenMesh::VPropHandleT cogs; - mesh.add_property(cogs); + const int iterations = 100; - // smoothing mesh N times - MyMesh::VertexIter v_it, v_end(mesh.vertices_end()); - MyMesh::VertexVertexIter vv_it; - MyMesh::Point cog; - MyMesh::Scalar valence; - unsigned int i, N(100); - - for (i=0; i < N; ++i) { - for (v_it = mesh.vertices_begin(); v_it != v_end; ++v_it) - { - mesh.property(cogs,*v_it).vectorize(0.0f); - valence = 0.0; + // Add a vertex property storing the computed centers of gravity + auto cog = OpenMesh::VProp(mesh); - for (vv_it = mesh.vv_iter( *v_it ); vv_it.is_valid(); ++vv_it) - { - mesh.property(cogs,*v_it) += mesh.point( *vv_it ); - ++valence; + // Smooth the mesh several times + for (int i = 0; i < iterations; ++i) { + // Iterate over all vertices to compute centers of gravity + for (const auto& vh : mesh.vertices()) { + cog[vh] = {0,0,0}; + int valence = 0; + // Iterate over all 1-ring vertices around vh + for (const auto& vvh : mesh.vv_range(vh)) { + cog[vh] += mesh.point(vvh); + ++valence; + } + cog[vh] /= valence; + } + // Move all vertices to the previously computed positions + for (const auto& vh : mesh.vertices()) { + mesh.point(vh) = cog[vh]; } - mesh.property(cogs,*v_it) /= valence; } - - for (v_it = mesh.vertices_begin(); v_it != v_end; ++v_it) - if ( !mesh.is_boundary( *v_it ) ) - mesh.set_point( *v_it, mesh.property(cogs,*v_it) ); - } + } // The cog vertex property is removed from the mesh at the end of this scope // write mesh ok = OpenMesh::IO::write_mesh(mesh, "smoothed_custom_properties_output.off"); @@ -488,8 +484,8 @@ TEST_F(OpenMeshTutorials, using_custom_properties) { TEST_F(OpenMeshTutorials, using_STL_algorithms) { MyMeshWithTraits mesh; - bool ok = OpenMesh::IO::read_mesh(mesh, "output.off"); - EXPECT_TRUE(ok) << "Cannot read mesh from file 'output.off'"; + bool ok = OpenMesh::IO::read_mesh(mesh, "cube_noisy.off"); + EXPECT_TRUE(ok) << "Cannot read mesh from file 'cube_noisy.off'"; SmootherT smoother(mesh); smoother.smooth(100); @@ -619,20 +615,20 @@ TEST_F(OpenMeshTutorials, deleting_geometry_elements) { mesh.request_vertex_status(); // generate vertices - MyMeshWithStatus::VertexHandle vhandle[8]; - MyMeshWithStatus::FaceHandle fhandle[6]; + Mesh::VertexHandle vhandle[8]; + Mesh::FaceHandle fhandle[6]; - vhandle[0] = mesh.add_vertex(MyMesh::Point(-1, -1, 1)); - vhandle[1] = mesh.add_vertex(MyMesh::Point( 1, -1, 1)); - vhandle[2] = mesh.add_vertex(MyMesh::Point( 1, 1, 1)); - vhandle[3] = mesh.add_vertex(MyMesh::Point(-1, 1, 1)); - vhandle[4] = mesh.add_vertex(MyMesh::Point(-1, -1, -1)); - vhandle[5] = mesh.add_vertex(MyMesh::Point( 1, -1, -1)); - vhandle[6] = mesh.add_vertex(MyMesh::Point( 1, 1, -1)); - vhandle[7] = mesh.add_vertex(MyMesh::Point(-1, 1, -1)); + vhandle[0] = mesh.add_vertex(Mesh::Point(-1, -1, 1)); + vhandle[1] = mesh.add_vertex(Mesh::Point( 1, -1, 1)); + vhandle[2] = mesh.add_vertex(Mesh::Point( 1, 1, 1)); + vhandle[3] = mesh.add_vertex(Mesh::Point(-1, 1, 1)); + vhandle[4] = mesh.add_vertex(Mesh::Point(-1, -1, -1)); + vhandle[5] = mesh.add_vertex(Mesh::Point( 1, -1, -1)); + vhandle[6] = mesh.add_vertex(Mesh::Point( 1, 1, -1)); + vhandle[7] = mesh.add_vertex(Mesh::Point(-1, 1, -1)); // generate (quadrilateral) faces - std::vector tmp_face_vhandles; + std::vector tmp_face_vhandles; tmp_face_vhandles.clear(); tmp_face_vhandles.push_back(vhandle[0]); tmp_face_vhandles.push_back(vhandle[1]); @@ -807,10 +803,10 @@ TEST_F(OpenMeshTutorials, flipping_edges) { Mesh mesh; // Add some vertices Mesh::VertexHandle vhandle[4]; - vhandle[0] = mesh.add_vertex(MyMesh::Point(0, 0, 0)); - vhandle[1] = mesh.add_vertex(MyMesh::Point(0, 1, 0)); - vhandle[2] = mesh.add_vertex(MyMesh::Point(1, 1, 0)); - vhandle[3] = mesh.add_vertex(MyMesh::Point(1, 0, 0)); + vhandle[0] = mesh.add_vertex(Mesh::Point(0, 0, 0)); + vhandle[1] = mesh.add_vertex(Mesh::Point(0, 1, 0)); + vhandle[2] = mesh.add_vertex(Mesh::Point(1, 1, 0)); + vhandle[3] = mesh.add_vertex(Mesh::Point(1, 0, 0)); // Add two faces std::vector face_vhandles; face_vhandles.push_back(vhandle[2]); @@ -846,13 +842,13 @@ TEST_F(OpenMeshTutorials, collapsing_edges) { mesh.request_edge_status(); // Add some vertices as in the illustration above PolyMesh::VertexHandle vhandle[7]; - vhandle[0] = mesh.add_vertex(MyMesh::Point(-1, 1, 0)); - vhandle[1] = mesh.add_vertex(MyMesh::Point(-1, 3, 0)); - vhandle[2] = mesh.add_vertex(MyMesh::Point(0, 0, 0)); - vhandle[3] = mesh.add_vertex(MyMesh::Point(0, 2, 0)); - vhandle[4] = mesh.add_vertex(MyMesh::Point(0, 4, 0)); - vhandle[5] = mesh.add_vertex(MyMesh::Point(1, 1, 0)); - vhandle[6] = mesh.add_vertex(MyMesh::Point(1, 3, 0)); + vhandle[0] = mesh.add_vertex(PolyMesh::Point(-1, 1, 0)); + vhandle[1] = mesh.add_vertex(PolyMesh::Point(-1, 3, 0)); + vhandle[2] = mesh.add_vertex(PolyMesh::Point(0, 0, 0)); + vhandle[3] = mesh.add_vertex(PolyMesh::Point(0, 2, 0)); + vhandle[4] = mesh.add_vertex(PolyMesh::Point(0, 4, 0)); + vhandle[5] = mesh.add_vertex(PolyMesh::Point(1, 1, 0)); + vhandle[6] = mesh.add_vertex(PolyMesh::Point(1, 3, 0)); // Add three quad faces std::vector face_vhandles; face_vhandles.push_back(vhandle[1]); @@ -886,4 +882,44 @@ TEST_F(OpenMeshTutorials, collapsing_edges) { // Our mesh now looks like in the illustration above after the collapsing. } +TEST_F(OpenMeshTutorials, using_smart_handles_and_smart_ranges) { + MyMesh mesh; + + bool ok = OpenMesh::IO::read_mesh(mesh, "cube_noisy.off"); + EXPECT_TRUE(ok) << "Cannot read mesh from file 'cube_noisy.off'"; + + const int iterations = 100; + + { + // Add a vertex property storing the laplace vector + auto laplace = OpenMesh::VProp(mesh); + + // Add a vertex property storing the laplace of the laplace + auto bi_laplace = OpenMesh::VProp(mesh); + + // Get a propertymanager of the points property of the mesh to use as functor + auto points = OpenMesh::getPointsProperty(mesh); + + // Smooth the mesh several times + for (int i = 0; i < iterations; ++i) { + // Iterate over all vertices to compute laplace vector + for (const auto& vh : mesh.vertices()) + laplace(vh) = vh.vertices().avg(points) - points(vh); + + // Iterate over all vertices to compute the laplace vector of the laplace vectors + for (const auto& vh : mesh.vertices()) + bi_laplace(vh) = (vh.vertices().avg(laplace) - laplace(vh)); + + // update points by substracting the bi-laplacian damped by a factor of 0.5 + for (const auto& vh : mesh.vertices()) + points(vh) += -0.5 * bi_laplace(vh); + } + } // The laplace and update properties are removed from the mesh at the end of this scope. + + // write mesh + ok = OpenMesh::IO::write_mesh(mesh, "smoothed_smart_output.off"); + + EXPECT_TRUE(ok) << "Cannot write mesh to file 'smoothed_smart_output.off'"; +} + } diff --git a/src/Unittests/unittests_vdpm.cc b/src/Unittests/unittests_vdpm.cc index 46a8110d..f037ca58 100644 --- a/src/Unittests/unittests_vdpm.cc +++ b/src/Unittests/unittests_vdpm.cc @@ -185,7 +185,7 @@ LoadInfo open_progresult_mesh(const std::string& _filename) OpenMesh::IO::restore(ifs, vr, swap); PMInfo pminfo; - pminfo.p0 = p; + pminfo.p0 = OpenMesh::vector_cast(p); pminfo.v0 = result.mesh.add_vertex(p); pminfo.v1 = Mesh::VertexHandle(v1); pminfo.vl = Mesh::VertexHandle(vl); diff --git a/src/Unittests/unittests_vector_type.cc b/src/Unittests/unittests_vector_type.cc index fb2378e4..98643d9e 100644 --- a/src/Unittests/unittests_vector_type.cc +++ b/src/Unittests/unittests_vector_type.cc @@ -263,6 +263,23 @@ TEST_F(OpenMeshVectorTest, BasicArithmeticImmutable) { EXPECT_NEAR(-2, v2neg[1], epsilon); EXPECT_NEAR(-3, v2neg[2], epsilon); } +template +void test_dot(const V1 &v1, const V2 &v2, const S&s) { + EXPECT_NEAR(s, v1 | v2, 1e-6); + EXPECT_NEAR(s, v1.dot(v2), 1e-6); + EXPECT_NEAR(-s, (-v1) | v2, 1e-6); + EXPECT_NEAR(-s, (-v1).dot(v2), 1e-6); + EXPECT_NEAR(s, v2 | v1, 1e-6); + EXPECT_NEAR(s, v2.dot(v1), 1e-6); +} + +template +void test_cross(const V1 &v1, const V2 &v2, const V3 &res) { + EXPECT_NEAR(0, (v1.cross(v2) - res).norm(), 1e-6); + EXPECT_NEAR(0, (v1 % v2 - res).norm(), 1e-6); + EXPECT_NEAR(0, (v2.cross(v1) + res).norm(), 1e-6); + EXPECT_NEAR(0, (v2 % v1 + res).norm(), 1e-6); +} TEST_F(OpenMeshVectorTest, BasicLinearAlgebra) { OpenMesh::Vec3d v(1, 2, 3); @@ -285,9 +302,15 @@ TEST_F(OpenMeshVectorTest, BasicLinearAlgebra) { EXPECT_EQ(1, OpenMesh::Vec3d(1, 3, -4).min_abs()); EXPECT_EQ(2, OpenMesh::Vec3d(-4, 2, 3).min_abs()); - EXPECT_NEAR(14, OpenMesh::Vec3d(1, 2, 3) | OpenMesh::Vec3d(1, 2, 3), 1e-6); - EXPECT_NEAR(-14, OpenMesh::Vec3d(1, 2, 3) | OpenMesh::Vec3d(-1, -2, -3), 1e-6); - EXPECT_NEAR(14, OpenMesh::Vec3d(-1, -2, -3) | OpenMesh::Vec3d(-1, -2, -3), 1e-6); + + test_dot(OpenMesh::Vec3d(1, 2, 3), OpenMesh::Vec3d(1, 2, 3), 14.); + test_dot(OpenMesh::Vec3d(1, 2, 3), OpenMesh::Vec3d(-1, -2, -3), -14.); + test_dot(OpenMesh::Vec3d(1, 2, 3), OpenMesh::Vec3i(1, 2, 3), 14); + test_dot(OpenMesh::Vec3i(1, 2, 3), OpenMesh::Vec3i(1, 2, 3), 14); + + test_cross(OpenMesh::Vec3i(2, 0, 0), OpenMesh::Vec3i(0, 3, 0), OpenMesh::Vec3i(0, 0, 6)); + test_cross(OpenMesh::Vec3d(2, 0, 0), OpenMesh::Vec3d(0, 3, 0), OpenMesh::Vec3d(0, 0, 6)); + test_cross(OpenMesh::Vec3d(2, 0, 0), OpenMesh::Vec3i(0, 3, 0), OpenMesh::Vec3d(0, 0, 6)); } TEST_F(OpenMeshVectorTest, array_init) { @@ -397,4 +420,19 @@ TEST_F(OpenMeshVectorGCCBugTest, alignment_bug) { } +TEST_F(OpenMeshVectorTest, Test_simple_0_constructor) { + + // Create a test vector with zeroes from one parameter + OpenMesh::Vec3d testVec = OpenMesh::Vec3d(0); + + EXPECT_EQ(0.0f, testVec[0]) << "Wrong Value after construction!"; + EXPECT_EQ(0.0f, testVec[1]) << "Wrong Value after construction!"; + EXPECT_EQ(0.0f, testVec[2]) << "Wrong Value after construction!"; + + + +} + + + }