diff --git a/cmake/ACGCommon.cmake b/cmake/ACGCommon.cmake index 200842a6..579d5b47 100644 --- a/cmake/ACGCommon.cmake +++ b/cmake/ACGCommon.cmake @@ -141,9 +141,22 @@ 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) @@ -160,6 +173,126 @@ macro (acg_qt4) 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 (Qt5Widgets QUIET) + find_package (Qt5Gui QUIET) + find_package (Qt5OpenGL QUIET) + + + if (Qt5Core_FOUND AND Qt5Widgets_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(${Qt5Widgets_INCLUDE_DIRS}) + include_directories(${Qt5Gui_INCLUDE_DIRS}) + include_directories(${Qt5OpenGL_INCLUDE_DIRS}) + add_definitions(${Qt5Core_DEFINITIONS}) + add_definitions(${Qt5Widgets_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 "") @@ -282,6 +415,51 @@ macro (acg_qt4_automoc moc_SRCS) 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) @@ -314,6 +492,37 @@ macro (acg_qt4_autouic uic_SRCS) 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) diff --git a/src/OpenMesh/Apps/CMakeLists.txt b/src/OpenMesh/Apps/CMakeLists.txt index 0063b740..15c7cd49 100644 --- a/src/OpenMesh/Apps/CMakeLists.txt +++ b/src/OpenMesh/Apps/CMakeLists.txt @@ -41,8 +41,14 @@ if ( BUILD_APPS ) 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 QT4_FOUND) + if (NOT QT5_FOUND AND NOT FORCE_QT4) + acg_qt5 () + endif() + if (NOT QT5_FOUND AND NOT QT4_FOUND) find_package (Qt4 COMPONENTS QtCore QtGui ) set (QT_USE_QTOPENGL 1) @@ -55,7 +61,8 @@ if ( BUILD_APPS ) endif() # check for OpenGL and GLUT as our required dependencies - if (QT4_FOUND AND OPENGL_FOUND AND GLUT_FOUND AND NOT "${CMAKE_GENERATOR}" MATCHES "MinGW Makefiles" ) + if ((QT5_FOUND OR QT4_FOUND) AND OPENGL_FOUND AND GLUT_FOUND AND NOT "${CMAKE_GENERATOR}" MATCHES "MinGW Makefiles" ) + add_subdirectory (Decimating/DecimaterGui) add_subdirectory (QtViewer) add_subdirectory (Subdivider/SubdividerGui) diff --git a/src/OpenMesh/Apps/Decimating/DecimaterGui/CMakeLists.txt b/src/OpenMesh/Apps/Decimating/DecimaterGui/CMakeLists.txt index 0749f13e..89d0596a 100644 --- a/src/OpenMesh/Apps/Decimating/DecimaterGui/CMakeLists.txt +++ b/src/OpenMesh/Apps/Decimating/DecimaterGui/CMakeLists.txt @@ -30,7 +30,11 @@ set (sources acg_drop_templates (sources) # genereate uic and moc targets -acg_qt4_automoc (moc_targets ${headers}) +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}) diff --git a/src/OpenMesh/Apps/ProgViewer/CMakeLists.txt b/src/OpenMesh/Apps/ProgViewer/CMakeLists.txt index bdbecc90..092d46cc 100644 --- a/src/OpenMesh/Apps/ProgViewer/CMakeLists.txt +++ b/src/OpenMesh/Apps/ProgViewer/CMakeLists.txt @@ -40,7 +40,11 @@ list (APPEND headers "../QtViewer/MeshViewerWidgetT.hh") acg_drop_templates (sources) # genereate uic and moc targets -acg_qt4_automoc (moc_targets ${headers}) +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}) diff --git a/src/OpenMesh/Apps/QtViewer/CMakeLists.txt b/src/OpenMesh/Apps/QtViewer/CMakeLists.txt index 5599334f..c3ac4846 100644 --- a/src/OpenMesh/Apps/QtViewer/CMakeLists.txt +++ b/src/OpenMesh/Apps/QtViewer/CMakeLists.txt @@ -23,8 +23,13 @@ acg_append_files (ui "*.ui" ${directories}) acg_drop_templates (sources) # genereate uic and moc targets -acg_qt4_autouic (uic_targets ${ui}) -acg_qt4_automoc (moc_targets ${headers}) +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) diff --git a/src/OpenMesh/Apps/QtViewer/QGLViewerWidget.hh b/src/OpenMesh/Apps/QtViewer/QGLViewerWidget.hh index 35d50bfb..3d4a8223 100644 --- a/src/OpenMesh/Apps/QtViewer/QGLViewerWidget.hh +++ b/src/OpenMesh/Apps/QtViewer/QGLViewerWidget.hh @@ -48,7 +48,7 @@ #include -#include +#include #include #include #include diff --git a/src/OpenMesh/Apps/Subdivider/SubdivideWidget.cc b/src/OpenMesh/Apps/Subdivider/SubdivideWidget.cc index f9defdae..ead70ff9 100644 --- a/src/OpenMesh/Apps/Subdivider/SubdivideWidget.cc +++ b/src/OpenMesh/Apps/Subdivider/SubdivideWidget.cc @@ -139,7 +139,7 @@ SubdivideWidget(QWidget* _parent, const char* _name) QButtonGroup* buttonGroup = new QButtonGroup(); - buttonGroup->setExclusive( TRUE ); + buttonGroup->setExclusive( true ); // insert 2 radiobuttons QRadioButton* radio1 = new QRadioButton( "Comp. Loop" ); @@ -149,7 +149,7 @@ SubdivideWidget(QWidget* _parent, const char* _name) QRadioButton* radio5 = new QRadioButton( "Interpolating Sqrt3" ); QRadioButton* radio6 = new QRadioButton( "Modified Butterfly" ); // QRadioButton* radio7 = new QRadioButton( "Catmull Clark" ); // Disabled, as it needs a quad mesh! - radio3->setChecked( TRUE ); + radio3->setChecked( true ); sel_topo_type = SOP_UniformLoop; buttonGroup->addButton(radio1, SOP_UniformCompositeLoop); diff --git a/src/OpenMesh/Apps/Subdivider/SubdividerGui/CMakeLists.txt b/src/OpenMesh/Apps/Subdivider/SubdividerGui/CMakeLists.txt index 9d1c436a..abc8f9f1 100644 --- a/src/OpenMesh/Apps/Subdivider/SubdividerGui/CMakeLists.txt +++ b/src/OpenMesh/Apps/Subdivider/SubdividerGui/CMakeLists.txt @@ -29,7 +29,11 @@ set (sources acg_drop_templates (sources) # genereate uic and moc targets -acg_qt4_automoc (moc_targets ${headers}) +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}) diff --git a/src/OpenMesh/Apps/VDProgMesh/Synthesizer/CMakeLists.txt b/src/OpenMesh/Apps/VDProgMesh/Synthesizer/CMakeLists.txt index 858ffa2c..ac1216ed 100644 --- a/src/OpenMesh/Apps/VDProgMesh/Synthesizer/CMakeLists.txt +++ b/src/OpenMesh/Apps/VDProgMesh/Synthesizer/CMakeLists.txt @@ -23,7 +23,11 @@ list (APPEND headers "../../QtViewer/MeshViewerWidgetT.hh") acg_drop_templates (sources) # genereate uic and moc targets -acg_qt4_automoc (moc_targets ${headers}) +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})