diff -Nru therion-6.0.4/CHANGES therion-6.0.5/CHANGES --- therion-6.0.4/CHANGES 2021-11-28 12:07:59.000000000 +0000 +++ therion-6.0.5/CHANGES 2022-02-20 13:23:28.000000000 +0000 @@ -1,3 +1,48 @@ +Therion 6.0.5 (2022-02-20): + +therion: + * added support for backtape/backlength readings + * warning if forwards and backwards readings do not match + (the difference threshold changed from 2 SD to 3 SD) + * some missing point and line types added to thbook [#401,402] + * Catch2 library updated to 2.3.18 + * bugs fixed: + - lox file generation segfault (solved by poly2tri library update) + - segfault caused by mixing local and global coordinate system + - unable to determine direction on zero-length path in scrap [#395] + +xtherion: + * added line section -direction to context menu + * bugs fixed: + - fixed a wrong translation + - wrong handling of filename open as argument + - SVG import fixed + +loch: + * added PLY walls export (File → Export) + * added support for cave volume calculation (Tools → Survey statistics) + +windows installer: + * updated 3rd party programs: + - Tcl/Tk 8.6.12, tkImg 1.4.13, BWidget 1.9.15 + - ImageMagick 7.1.0-24 + - W32TeX 2021/06/24 + - InnoSetup 6.2.0 + * support for multiple languages during the installation + * two variants available now: + - built on Windows using MSYS2 environment; contains up-to-date libraries; + dynamically linked (a lot of DLLs are included) + [this is now the default for releases] + - built on Linux using MXE cross-compiler; some of the libraries are + quite outdated; statically linked; smaller instaler size + [the only option used between 5.4.0 and 6.0.4 to build the installer] + +cmake: + * support for collecting the required DLLs for deployment [#397] + (thanks to Matěj Plch) + +-------------------------------------------------------------------------------- + Therion 6.0.4 (2021-11-28): therion: diff -Nru therion-6.0.4/cmake/Dependencies.cmake therion-6.0.5/cmake/Dependencies.cmake --- therion-6.0.4/cmake/Dependencies.cmake 2021-11-28 12:07:59.000000000 +0000 +++ therion-6.0.5/cmake/Dependencies.cmake 2022-02-20 13:23:28.000000000 +0000 @@ -49,6 +49,7 @@ vtkCommonExecutionModel vtkCommonDataModel vtkCommonCore + vtkIOPLY vtkFiltersCore vtkFiltersHybrid vtkIOLegacy diff -Nru therion-6.0.4/cmake/Deploy.cmake therion-6.0.5/cmake/Deploy.cmake --- therion-6.0.4/cmake/Deploy.cmake 1970-01-01 00:00:00.000000000 +0000 +++ therion-6.0.5/cmake/Deploy.cmake 2022-02-20 13:23:28.000000000 +0000 @@ -0,0 +1,12 @@ +# Find all DLL dependencies to deploy on Windows. +include(GetPrerequisites) +get_prerequisites(${THERION} DLLS 1 1 "" "") +get_prerequisites(${LOCH} DLLS 1 1 "" "") + +file(MAKE_DIRECTORY ${DLLS_DIR}) + +foreach(DLL ${DLLS}) + gp_resolve_item("" ${DLL} "" "" RESOLVED) + message("Copying dependency: ${RESOLVED}") + file(COPY ${RESOLVED} DESTINATION ${DLLS_DIR}) +endforeach() diff -Nru therion-6.0.4/cmake/LochSources.cmake therion-6.0.5/cmake/LochSources.cmake --- therion-6.0.4/cmake/LochSources.cmake 2021-11-28 12:07:59.000000000 +0000 +++ therion-6.0.5/cmake/LochSources.cmake 2022-02-20 13:23:28.000000000 +0000 @@ -19,6 +19,7 @@ lxR2D.h lxSetup.h lxSTree.h + lxSStats.h lxTR.h ) @@ -38,5 +39,6 @@ lxRender.cxx lxSScene.cxx lxSView.cxx + lxSStats.cxx lxTR.c ) diff -Nru therion-6.0.4/CMakeLists.txt therion-6.0.5/CMakeLists.txt --- therion-6.0.4/CMakeLists.txt 2021-11-28 12:07:59.000000000 +0000 +++ therion-6.0.5/CMakeLists.txt 2022-02-20 13:23:28.000000000 +0000 @@ -190,3 +190,15 @@ add_subdirectory(loch) add_subdirectory(thbook) add_subdirectory(xtherion) + +# deployment of DLL dependencies on Windows +if (BUILD_THERION AND BUILD_LOCH AND WIN32) + set(DLLS_DIR ${CMAKE_BINARY_DIR}/dependencies) + add_custom_target(deploy + ${CMAKE_COMMAND} -D THERION=$ + -D LOCH=$ + -D DLLS_DIR=${DLLS_DIR} + -P cmake/Deploy.cmake + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) + set_target_properties(deploy PROPERTIES ADDITIONAL_CLEAN_FILES ${DLLS_DIR}) +endif() diff -Nru therion-6.0.4/debian/changelog therion-6.0.5/debian/changelog --- therion-6.0.4/debian/changelog 2022-02-15 17:12:12.000000000 +0000 +++ therion-6.0.5/debian/changelog 2022-02-20 13:35:37.000000000 +0000 @@ -1,14 +1,8 @@ -therion (6.0.4-1build2) jammy; urgency=medium +therion (6.0.5-1) unstable; urgency=medium - * No-change rebuild against libvtk9.1 + * New upstream release. - -- Graham Inggs Tue, 15 Feb 2022 17:12:12 +0000 - -therion (6.0.4-1build1) jammy; urgency=medium - - * No-change rebuild against libfmt8 - - -- Graham Inggs Fri, 24 Dec 2021 14:17:10 +0000 + -- Martin Budaj Sun, 20 Feb 2022 14:35:37 +0100 therion (6.0.4-1) unstable; urgency=medium diff -Nru therion-6.0.4/extern/catch2/catch.hpp therion-6.0.5/extern/catch2/catch.hpp --- therion-6.0.4/extern/catch2/catch.hpp 2021-11-28 12:07:59.000000000 +0000 +++ therion-6.0.5/extern/catch2/catch.hpp 2022-02-20 13:23:28.000000000 +0000 @@ -1,9 +1,9 @@ /* - * Catch v2.13.6 - * Generated: 2021-04-16 18:23:38.044268 + * Catch v2.13.8 + * Generated: 2022-01-03 21:20:09.589503 * ---------------------------------------------------------- * This file has been merged from multiple headers. Please don't edit it directly - * Copyright (c) 2021 Two Blue Cubes Ltd. All rights reserved. + * Copyright (c) 2022 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -15,7 +15,7 @@ #define CATCH_VERSION_MAJOR 2 #define CATCH_VERSION_MINOR 13 -#define CATCH_VERSION_PATCH 6 +#define CATCH_VERSION_PATCH 8 #ifdef __clang__ # pragma clang system_header @@ -240,9 +240,6 @@ // Visual C++ #if defined(_MSC_VER) -# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) ) -# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma( warning(pop) ) - // Universal Windows platform does not support SEH // Or console colours (or console at all...) # if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) @@ -251,13 +248,18 @@ # define CATCH_INTERNAL_CONFIG_WINDOWS_SEH # endif +# if !defined(__clang__) // Handle Clang masquerading for msvc + // MSVC traditional preprocessor needs some workaround for __VA_ARGS__ // _MSVC_TRADITIONAL == 0 means new conformant preprocessor // _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor -# if !defined(__clang__) // Handle Clang masquerading for msvc # if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL) # define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR # endif // MSVC_TRADITIONAL + +// Only do this if we're not using clang on Windows, which uses `diagnostic push` & `diagnostic pop` +# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) ) +# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma( warning(pop) ) # endif // __clang__ #endif // _MSC_VER @@ -326,7 +328,7 @@ // Check if byte is available and usable # if __has_include() && defined(CATCH_CPP17_OR_GREATER) # include - # if __cpp_lib_byte > 0 + # if defined(__cpp_lib_byte) && (__cpp_lib_byte > 0) # define CATCH_INTERNAL_CONFIG_CPP17_BYTE # endif # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) @@ -1010,34 +1012,34 @@ #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \ - INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ ) + INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename TestType, __VA_ARGS__ ) #else #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \ - INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ ) ) + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename TestType, __VA_ARGS__ ) ) #endif #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \ - INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ ) + INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ ) #else #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \ - INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ ) ) + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ ) ) #endif #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \ - INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) + INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) #else #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \ - INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) ) + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) ) #endif #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \ - INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) + INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) #else #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \ - INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) ) + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) ) #endif #endif @@ -1050,7 +1052,7 @@ CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \ static void TestName() #define INTERNAL_CATCH_TESTCASE( ... ) \ - INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ ) + INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ), __VA_ARGS__ ) /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \ @@ -1072,7 +1074,7 @@ CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \ void TestName::test() #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \ - INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ ) + INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ), ClassName, __VA_ARGS__ ) /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \ @@ -1113,18 +1115,18 @@ #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \ - INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ ) + INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename TestType, __VA_ARGS__ ) #else #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \ - INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ ) ) + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename TestType, __VA_ARGS__ ) ) #endif #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \ - INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ ) + INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ ) #else #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \ - INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ ) ) + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ ) ) #endif #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(TestName, TestFuncName, Name, Tags, Signature, TmplTypes, TypesList) \ @@ -1162,18 +1164,18 @@ #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\ - INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename T,__VA_ARGS__) + INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename T,__VA_ARGS__) #else #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\ - INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename T, __VA_ARGS__ ) ) + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename T, __VA_ARGS__ ) ) #endif #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\ - INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__) + INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__) #else #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\ - INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ ) ) + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ ) ) #endif #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2(TestName, TestFunc, Name, Tags, TmplList)\ @@ -1204,7 +1206,7 @@ static void TestFunc() #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(Name, Tags, TmplList) \ - INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, TmplList ) + INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, TmplList ) #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... ) \ CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ @@ -1237,18 +1239,18 @@ #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \ - INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) + INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) #else #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \ - INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) ) + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) ) #endif #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \ - INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) + INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) #else #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \ - INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) ) + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) ) #endif #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2(TestNameClass, TestName, ClassName, Name, Tags, Signature, TmplTypes, TypesList)\ @@ -1289,18 +1291,18 @@ #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\ - INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, typename T, __VA_ARGS__ ) + INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, typename T, __VA_ARGS__ ) #else #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\ - INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, typename T,__VA_ARGS__ ) ) + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, typename T,__VA_ARGS__ ) ) #endif #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\ - INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, Signature, __VA_ARGS__ ) + INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, Signature, __VA_ARGS__ ) #else #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\ - INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, Signature,__VA_ARGS__ ) ) + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, Signature,__VA_ARGS__ ) ) #endif #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, TmplList) \ @@ -1334,7 +1336,7 @@ void TestName::test() #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD(ClassName, Name, Tags, TmplList) \ - INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, TmplList ) + INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, TmplList ) // end catch_test_registry.h // start catch_capture.hpp @@ -3091,7 +3093,7 @@ Approx operator-() const; template ::value>::type> - Approx operator()( T const& value ) { + Approx operator()( T const& value ) const { Approx approx( static_cast(value) ); approx.m_epsilon = m_epsilon; approx.m_margin = m_margin; @@ -4163,7 +4165,7 @@ if (!m_predicate(m_generator.get())) { // It might happen that there are no values that pass the // filter. In that case we throw an exception. - auto has_initial_value = next(); + auto has_initial_value = nextImpl(); if (!has_initial_value) { Catch::throw_exception(GeneratorException("No valid value found in filtered generator")); } @@ -4175,6 +4177,11 @@ } bool next() override { + return nextImpl(); + } + + private: + bool nextImpl() { bool success = m_generator.next(); if (!success) { return false; @@ -5458,6 +5465,8 @@ } // namespace Catch // end catch_outlier_classification.hpp + +#include #endif // CATCH_CONFIG_ENABLE_BENCHMARKING #include @@ -6342,9 +6351,10 @@ void writeTestCase(TestCaseNode const& testCaseNode); - void writeSection(std::string const& className, - std::string const& rootName, - SectionNode const& sectionNode); + void writeSection( std::string const& className, + std::string const& rootName, + SectionNode const& sectionNode, + bool testOkToFail ); void writeAssertions(SectionNode const& sectionNode); void writeAssertion(AssertionStats const& stats); @@ -6879,7 +6889,7 @@ } iters *= 2; } - throw optimized_away_error{}; + Catch::throw_exception(optimized_away_error{}); } } // namespace Detail } // namespace Benchmark @@ -6887,6 +6897,7 @@ // end catch_run_for_at_least.hpp #include +#include namespace Catch { namespace Benchmark { @@ -15376,7 +15387,7 @@ } Version const& libraryVersion() { - static Version version( 2, 13, 6, "", 0 ); + static Version version( 2, 13, 8, "", 0 ); return version; } @@ -16789,6 +16800,7 @@ #include #include #include +#include namespace Catch { @@ -16816,7 +16828,7 @@ #else std::strftime(timeStamp, timeStampSize, fmt, timeInfo); #endif - return std::string(timeStamp); + return std::string(timeStamp, timeStampSize-1); } std::string fileNameTag(const std::vector &tags) { @@ -16827,6 +16839,17 @@ return it->substr(1); return std::string(); } + + // Formats the duration in seconds to 3 decimal places. + // This is done because some genius defined Maven Surefire schema + // in a way that only accepts 3 decimal places, and tools like + // Jenkins use that schema for validation JUnit reporter output. + std::string formatDuration( double seconds ) { + ReusableStringStream rss; + rss << std::fixed << std::setprecision( 3 ) << seconds; + return rss.str(); + } + } // anonymous namespace JunitReporter::JunitReporter( ReporterConfig const& _config ) @@ -16896,7 +16919,7 @@ if( m_config->showDurations() == ShowDurations::Never ) xml.writeAttribute( "time", "" ); else - xml.writeAttribute( "time", suiteTime ); + xml.writeAttribute( "time", formatDuration( suiteTime ) ); xml.writeAttribute( "timestamp", getCurrentTimestamp() ); // Write properties if there are any @@ -16941,12 +16964,13 @@ if ( !m_config->name().empty() ) className = m_config->name() + "." + className; - writeSection( className, "", rootSection ); + writeSection( className, "", rootSection, stats.testInfo.okToFail() ); } - void JunitReporter::writeSection( std::string const& className, - std::string const& rootName, - SectionNode const& sectionNode ) { + void JunitReporter::writeSection( std::string const& className, + std::string const& rootName, + SectionNode const& sectionNode, + bool testOkToFail) { std::string name = trim( sectionNode.stats.sectionInfo.name ); if( !rootName.empty() ) name = rootName + '/' + name; @@ -16963,13 +16987,18 @@ xml.writeAttribute( "classname", className ); xml.writeAttribute( "name", name ); } - xml.writeAttribute( "time", ::Catch::Detail::stringify( sectionNode.stats.durationInSeconds ) ); + xml.writeAttribute( "time", formatDuration( sectionNode.stats.durationInSeconds ) ); // This is not ideal, but it should be enough to mimic gtest's // junit output. // Ideally the JUnit reporter would also handle `skipTest` // events and write those out appropriately. xml.writeAttribute( "status", "run" ); + if (sectionNode.stats.assertions.failedButOk) { + xml.scopedElement("skipped") + .writeAttribute("message", "TEST_CASE tagged with !mayfail"); + } + writeAssertions( sectionNode ); if( !sectionNode.stdOut.empty() ) @@ -16979,9 +17008,9 @@ } for( auto const& childNode : sectionNode.childSections ) if( className.empty() ) - writeSection( name, "", *childNode ); + writeSection( name, "", *childNode, testOkToFail ); else - writeSection( className, name, *childNode ); + writeSection( className, name, *childNode, testOkToFail ); } void JunitReporter::writeAssertions( SectionNode const& sectionNode ) { @@ -17626,9 +17655,9 @@ #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) #define CATCH_BENCHMARK(...) \ - INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,)) + INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(C_A_T_C_H_B_E_N_C_H_), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,)) #define CATCH_BENCHMARK_ADVANCED(name) \ - INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), name) + INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(C_A_T_C_H_B_E_N_C_H_), name) #endif // CATCH_CONFIG_ENABLE_BENCHMARKING // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required @@ -17730,9 +17759,9 @@ #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) #define BENCHMARK(...) \ - INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,)) + INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(C_A_T_C_H_B_E_N_C_H_), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,)) #define BENCHMARK_ADVANCED(name) \ - INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), name) + INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(C_A_T_C_H_B_E_N_C_H_), name) #endif // CATCH_CONFIG_ENABLE_BENCHMARKING using Catch::Detail::Approx; @@ -17779,8 +17808,8 @@ #define CATCH_WARN( msg ) (void)(0) #define CATCH_CAPTURE( msg ) (void)(0) -#define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) -#define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) +#define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ )) +#define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ )) #define CATCH_METHOD_AS_TEST_CASE( method, ... ) #define CATCH_REGISTER_TEST_CASE( Function, ... ) (void)(0) #define CATCH_SECTION( ... ) @@ -17789,7 +17818,7 @@ #define CATCH_FAIL_CHECK( ... ) (void)(0) #define CATCH_SUCCEED( ... ) (void)(0) -#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) +#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ )) #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) @@ -17812,8 +17841,8 @@ #endif // "BDD-style" convenience wrappers -#define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) -#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className ) +#define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ )) +#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ), className ) #define CATCH_GIVEN( desc ) #define CATCH_AND_GIVEN( desc ) #define CATCH_WHEN( desc ) @@ -17863,8 +17892,8 @@ #define WARN( msg ) (void)(0) #define CAPTURE( msg ) (void)(0) -#define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) -#define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) +#define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ )) +#define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ )) #define METHOD_AS_TEST_CASE( method, ... ) #define REGISTER_TEST_CASE( Function, ... ) (void)(0) #define SECTION( ... ) @@ -17872,7 +17901,7 @@ #define FAIL( ... ) (void)(0) #define FAIL_CHECK( ... ) (void)(0) #define SUCCEED( ... ) (void)(0) -#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) +#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ )) #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) @@ -17902,8 +17931,8 @@ #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature ) // "BDD-style" convenience wrappers -#define SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) ) -#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className ) +#define SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ) ) +#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ), className ) #define GIVEN( desc ) #define AND_GIVEN( desc ) diff -Nru therion-6.0.4/extern/poly2tri/common/shapes.cc therion-6.0.5/extern/poly2tri/common/shapes.cc --- therion-6.0.4/extern/poly2tri/common/shapes.cc 2021-11-28 12:07:59.000000000 +0000 +++ therion-6.0.5/extern/poly2tri/common/shapes.cc 2022-02-20 13:23:28.000000000 +0000 @@ -1,6 +1,6 @@ /* - * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors - * http://code.google.com/p/poly2tri/ + * Poly2Tri Copyright (c) 2009-2018, Poly2Tri Contributors + * https://github.com/jhasse/poly2tri * * All rights reserved. * @@ -29,14 +29,24 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "shapes.h" + +#include #include namespace p2t { +Point::Point(double x, double y) : x(x), y(y) +{ +} + +std::ostream& operator<<(std::ostream& out, const Point& point) { + return out << point.x << "," << point.y; +} + Triangle::Triangle(Point& a, Point& b, Point& c) { points_[0] = &a; points_[1] = &b; points_[2] = &c; - neighbors_[0] = NULL; neighbors_[1] = NULL; neighbors_[2] = NULL; + neighbors_[0] = nullptr; neighbors_[1] = nullptr; neighbors_[2] = nullptr; constrained_edge[0] = constrained_edge[1] = constrained_edge[2] = false; delaunay_edge[0] = delaunay_edge[1] = delaunay_edge[2] = false; interior_ = false; @@ -52,8 +62,7 @@ else if ((p1 == points_[0] && p2 == points_[1]) || (p1 == points_[1] && p2 == points_[0])) neighbors_[2] = t; else - throw(0); - //assert(0); + assert(0); } // Exhaustive search to update neighbor pointers @@ -80,36 +89,36 @@ for( int i=0; i<3; i++ ) { t = neighbors_[i]; - if( t != NULL ) + if( t != nullptr ) { t->ClearNeighbor( this ); } } ClearNeighbors(); - points_[0]=points_[1]=points_[2] = NULL; + points_[0]=points_[1]=points_[2] = nullptr; } void Triangle::ClearNeighbor(const Triangle *triangle ) { if( neighbors_[0] == triangle ) { - neighbors_[0] = NULL; + neighbors_[0] = nullptr; } else if( neighbors_[1] == triangle ) { - neighbors_[1] = NULL; + neighbors_[1] = nullptr; } else { - neighbors_[2] = NULL; + neighbors_[2] = nullptr; } } void Triangle::ClearNeighbors() { - neighbors_[0] = NULL; - neighbors_[1] = NULL; - neighbors_[2] = NULL; + neighbors_[0] = nullptr; + neighbors_[1] = nullptr; + neighbors_[2] = nullptr; } void Triangle::ClearDelunayEdges() @@ -147,8 +156,7 @@ points_[2] = points_[1]; points_[1] = &npoint; } else { - throw(0); - //assert(0); + assert(0); } } @@ -161,8 +169,7 @@ } else if (p == points_[2]) { return 2; } - throw(0); - //assert(0); + assert(0); return -1; } @@ -222,9 +229,8 @@ } else if (&point == points_[2]) { return points_[1]; } - throw(0); - //assert(0); - return NULL; + assert(0); + return nullptr; } // The point counter-clockwise to given point @@ -237,9 +243,19 @@ } else if (&point == points_[2]) { return points_[0]; } - throw(0); - //assert(0); - return NULL; + assert(0); + return nullptr; +} + +// The neighbor across to given point +Triangle* Triangle::NeighborAcross(const Point& point) +{ + if (&point == points_[0]) { + return neighbors_[0]; + } else if (&point == points_[1]) { + return neighbors_[1]; + } + return neighbors_[2]; } // The neighbor clockwise to given point @@ -348,23 +364,50 @@ } } -// The neighbor across to given point -Triangle& Triangle::NeighborAcross(const Point& opoint) +void Triangle::DebugPrint() { - if (&opoint == points_[0]) { - return *neighbors_[0]; - } else if (&opoint == points_[1]) { - return *neighbors_[1]; - } - return *neighbors_[2]; + std::cout << *points_[0] << " " << *points_[1] << " " << *points_[2] << std::endl; } -void Triangle::DebugPrint() +bool Triangle::CircumcicleContains(const Point& point) const +{ + assert(IsCounterClockwise()); + const double dx = points_[0]->x - point.x; + const double dy = points_[0]->y - point.y; + const double ex = points_[1]->x - point.x; + const double ey = points_[1]->y - point.y; + const double fx = points_[2]->x - point.x; + const double fy = points_[2]->y - point.y; + + const double ap = dx * dx + dy * dy; + const double bp = ex * ex + ey * ey; + const double cp = fx * fx + fy * fy; + + return (dx * (fy * bp - cp * ey) - dy * (fx * bp - cp * ex) + ap * (fx * ey - fy * ex)) < 0; +} + +bool Triangle::IsCounterClockwise() const +{ + return (points_[1]->x - points_[0]->x) * (points_[2]->y - points_[0]->y) - + (points_[2]->x - points_[0]->x) * (points_[1]->y - points_[0]->y) > + 0; +} + +bool IsDelaunay(const std::vector& triangles) { - using namespace std; - cout << points_[0]->x << "," << points_[0]->y << " "; - cout << points_[1]->x << "," << points_[1]->y << " "; - cout << points_[2]->x << "," << points_[2]->y << endl; + for (const auto triangle : triangles) { + for (const auto other : triangles) { + if (triangle == other) { + continue; + } + for (int i = 0; i < 3; ++i) { + if (triangle->CircumcicleContains(*other->GetPoint(i))) { + return false; + } + } + } + } + return true; } } diff -Nru therion-6.0.4/extern/poly2tri/common/shapes.h therion-6.0.5/extern/poly2tri/common/shapes.h --- therion-6.0.4/extern/poly2tri/common/shapes.h 2021-11-28 12:07:59.000000000 +0000 +++ therion-6.0.5/extern/poly2tri/common/shapes.h 2022-02-20 13:23:28.000000000 +0000 @@ -1,6 +1,6 @@ /* - * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors - * http://code.google.com/p/poly2tri/ + * Poly2Tri Copyright (c) 2009-2018, Poly2Tri Contributors + * https://github.com/jhasse/poly2tri * * All rights reserved. * @@ -33,10 +33,10 @@ #ifndef SHAPES_H #define SHAPES_H -#include -#include -#include #include +#include +#include +#include namespace p2t { @@ -57,7 +57,7 @@ std::vector edge_list; /// Construct using coordinates. - Point(double x, double y) : x(x), y(y) {} + Point(double x, double y); /// Set this point to all zeros. void set_zero() @@ -119,6 +119,8 @@ }; +std::ostream& operator<<(std::ostream&, const Point&); + // Represents a simple polygon's edge struct Edge { @@ -136,8 +138,7 @@ p = &p2; } else if (p1.x == p2.x) { // Repeat points - //assert(false); - throw(0); + throw std::runtime_error("Edge::Edge: p1 == p2"); } } @@ -175,6 +176,7 @@ int Index(const Point* p); int EdgeIndex(const Point* p1, const Point* p2); +Triangle* NeighborAcross(const Point& point); Triangle* NeighborCW(const Point& point); Triangle* NeighborCCW(const Point& point); bool GetConstrainedEdgeCCW(const Point& p); @@ -202,12 +204,14 @@ inline bool IsInterior(); inline void IsInterior(bool b); -Triangle& NeighborAcross(const Point& opoint); - void DebugPrint(); +bool CircumcicleContains(const Point&) const; + private: +bool IsCounterClockwise() const; + /// Triangle points Point* points_[3]; /// Neighbor list @@ -255,7 +259,7 @@ inline bool operator !=(const Point& a, const Point& b) { - return !(a.x == b.x) && !(a.y == b.y); + return !(a.x == b.x) || !(a.y == b.y); } /// Peform the dot product on two vectors. @@ -319,6 +323,9 @@ interior_ = b; } +/// Is this set a valid delaunay triangulation? +bool IsDelaunay(const std::vector&); + } #endif diff -Nru therion-6.0.4/extern/poly2tri/common/utils.h therion-6.0.5/extern/poly2tri/common/utils.h --- therion-6.0.4/extern/poly2tri/common/utils.h 2021-11-28 12:07:59.000000000 +0000 +++ therion-6.0.5/extern/poly2tri/common/utils.h 2022-02-20 13:23:28.000000000 +0000 @@ -1,6 +1,6 @@ /* - * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors - * http://code.google.com/p/poly2tri/ + * Poly2Tri Copyright (c) 2009-2018, Poly2Tri Contributors + * https://github.com/jhasse/poly2tri * * All rights reserved. * @@ -35,8 +35,10 @@ // Otherwise #defines like M_PI are undeclared under Visual Studio #define _USE_MATH_DEFINES +#include "shapes.h" + +#include #include -#include // C99 removes M_PI from math.h #ifndef M_PI diff -Nru therion-6.0.4/extern/poly2tri/poly2tri.h therion-6.0.5/extern/poly2tri/poly2tri.h --- therion-6.0.4/extern/poly2tri/poly2tri.h 2021-11-28 12:07:59.000000000 +0000 +++ therion-6.0.5/extern/poly2tri/poly2tri.h 2022-02-20 13:23:28.000000000 +0000 @@ -1,6 +1,6 @@ /* - * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors - * http://code.google.com/p/poly2tri/ + * Poly2Tri Copyright (c) 2009-2018, Poly2Tri Contributors + * https://github.com/jhasse/poly2tri * * All rights reserved. * @@ -35,4 +35,4 @@ #include "common/shapes.h" #include "sweep/cdt.h" -#endif \ No newline at end of file +#endif diff -Nru therion-6.0.4/extern/poly2tri/sweep/advancing_front.cc therion-6.0.5/extern/poly2tri/sweep/advancing_front.cc --- therion-6.0.4/extern/poly2tri/sweep/advancing_front.cc 2021-11-28 12:07:59.000000000 +0000 +++ therion-6.0.5/extern/poly2tri/sweep/advancing_front.cc 2022-02-20 13:23:28.000000000 +0000 @@ -1,6 +1,6 @@ /* - * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors - * http://code.google.com/p/poly2tri/ + * Poly2Tri Copyright (c) 2009-2018, Poly2Tri Contributors + * https://github.com/jhasse/poly2tri * * All rights reserved. * @@ -30,6 +30,8 @@ */ #include "advancing_front.h" +#include + namespace p2t { AdvancingFront::AdvancingFront(Node& head, Node& tail) @@ -44,21 +46,21 @@ Node* node = search_node_; if (x < node->value) { - while ((node = node->prev) != NULL) { + while ((node = node->prev) != nullptr) { if (x >= node->value) { search_node_ = node; return node; } } } else { - while ((node = node->next) != NULL) { + while ((node = node->next) != nullptr) { if (x < node->value) { search_node_ = node->prev; return node->prev; } } } - return NULL; + return nullptr; } Node* AdvancingFront::FindSearchNode(double x) @@ -86,13 +88,13 @@ } } } else if (px < nx) { - while ((node = node->prev) != NULL) { + while ((node = node->prev) != nullptr) { if (point == node->point) { break; } } } else { - while ((node = node->next) != NULL) { + while ((node = node->next) != nullptr) { if (point == node->point) break; } @@ -105,4 +107,4 @@ { } -} \ No newline at end of file +} diff -Nru therion-6.0.4/extern/poly2tri/sweep/advancing_front.h therion-6.0.5/extern/poly2tri/sweep/advancing_front.h --- therion-6.0.4/extern/poly2tri/sweep/advancing_front.h 2021-11-28 12:07:59.000000000 +0000 +++ therion-6.0.5/extern/poly2tri/sweep/advancing_front.h 2022-02-20 13:23:28.000000000 +0000 @@ -1,6 +1,6 @@ /* - * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors - * http://code.google.com/p/poly2tri/ + * Poly2Tri Copyright (c) 2009-2018, Poly2Tri Contributors + * https://github.com/jhasse/poly2tri * * All rights reserved. * @@ -115,4 +115,4 @@ } -#endif \ No newline at end of file +#endif diff -Nru therion-6.0.4/extern/poly2tri/sweep/cdt.cc therion-6.0.5/extern/poly2tri/sweep/cdt.cc --- therion-6.0.4/extern/poly2tri/sweep/cdt.cc 2021-11-28 12:07:59.000000000 +0000 +++ therion-6.0.5/extern/poly2tri/sweep/cdt.cc 2022-02-20 13:23:28.000000000 +0000 @@ -1,6 +1,6 @@ /* - * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors - * http://code.google.com/p/poly2tri/ + * Poly2Tri Copyright (c) 2009-2021, Poly2Tri Contributors + * https://github.com/jhasse/poly2tri * * All rights reserved. * @@ -68,4 +68,4 @@ delete sweep_; } -} \ No newline at end of file +} // namespace p2t diff -Nru therion-6.0.4/extern/poly2tri/sweep/cdt.h therion-6.0.5/extern/poly2tri/sweep/cdt.h --- therion-6.0.4/extern/poly2tri/sweep/cdt.h 2021-11-28 12:07:59.000000000 +0000 +++ therion-6.0.5/extern/poly2tri/sweep/cdt.h 2022-02-20 13:23:28.000000000 +0000 @@ -1,6 +1,6 @@ /* - * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors - * http://code.google.com/p/poly2tri/ + * Poly2Tri Copyright (c) 2009-2018, Poly2Tri Contributors + * https://github.com/jhasse/poly2tri * * All rights reserved. * @@ -102,4 +102,4 @@ } -#endif \ No newline at end of file +#endif diff -Nru therion-6.0.4/extern/poly2tri/sweep/sweep.cc therion-6.0.5/extern/poly2tri/sweep/sweep.cc --- therion-6.0.4/extern/poly2tri/sweep/sweep.cc 2021-11-28 12:07:59.000000000 +0000 +++ therion-6.0.5/extern/poly2tri/sweep/sweep.cc 2022-02-20 13:23:28.000000000 +0000 @@ -1,6 +1,6 @@ /* - * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors - * http://code.google.com/p/poly2tri/ + * Poly2Tri Copyright (c) 2009-2018, Poly2Tri Contributors + * https://github.com/jhasse/poly2tri * * All rights reserved. * @@ -28,19 +28,21 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include #include "sweep.h" #include "sweep_context.h" #include "advancing_front.h" #include "../common/utils.h" +#include +#include + namespace p2t { // Triangulate simple polygon with holes void Sweep::Triangulate(SweepContext& tcx) { tcx.InitTriangulation(); - tcx.CreateAdvancingFront(nodes_); + tcx.CreateAdvancingFront(); // Sweep points; build mesh SweepPoints(tcx); // Clean up @@ -52,8 +54,8 @@ for (size_t i = 1; i < tcx.point_count(); i++) { Point& point = *tcx.GetPoint(i); Node* node = &PointEvent(tcx, point); - for (unsigned int i = 0; i < point.edge_list.size(); i++) { - EdgeEvent(tcx, point.edge_list[i], node); + for (unsigned int j = 0; j < point.edge_list.size(); j++) { + EdgeEvent(tcx, point.edge_list[j], node); } } } @@ -63,17 +65,25 @@ // Get an Internal triangle to start with Triangle* t = tcx.front()->head()->next->triangle; Point* p = tcx.front()->head()->next->point; - while (!t->GetConstrainedEdgeCW(*p)) { + while (t && !t->GetConstrainedEdgeCW(*p)) { t = t->NeighborCCW(*p); } // Collect interior triangles constrained by edges - tcx.MeshClean(*t); + if (t) { + tcx.MeshClean(*t); + } } Node& Sweep::PointEvent(SweepContext& tcx, Point& point) { - Node& node = tcx.LocateNode(point); + Node* node_ptr = tcx.LocateNode(point); + if (!node_ptr || !node_ptr->point || !node_ptr->next || !node_ptr->next->point) + { + throw std::runtime_error("PointEvent - null node"); + } + + Node& node = *node_ptr; Node& new_node = NewFrontTriangle(tcx, point, node); // Only need to check +epsilon since point never have smaller @@ -106,6 +116,9 @@ void Sweep::EdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle* triangle, Point& point) { + if (triangle == nullptr) { + throw std::runtime_error("EdgeEvent - null triangle"); + } if (IsEdgeSideOfTriangle(*triangle, ep, eq)) { return; } @@ -113,17 +126,15 @@ Point* p1 = triangle->PointCCW(point); Orientation o1 = Orient2d(eq, *p1, ep); if (o1 == COLLINEAR) { - if( triangle->Contains(&eq, p1)) { - triangle->MarkConstrainedEdge(&eq, p1 ); + if (triangle->Contains(&eq, p1)) { + triangle->MarkConstrainedEdge(&eq, p1); // We are modifying the constraint maybe it would be better to // not change the given constraint and just keep a variable for the new constraint tcx.edge_event.constrained_edge->q = p1; - triangle = &triangle->NeighborAcross(point); - EdgeEvent( tcx, ep, *p1, triangle, *p1 ); + triangle = triangle->NeighborAcross(point); + EdgeEvent(tcx, ep, *p1, triangle, *p1); } else { - std::runtime_error("EdgeEvent - collinear points not supported"); - throw(0); - //assert(0); + throw std::runtime_error("EdgeEvent - collinear points not supported"); } return; } @@ -131,17 +142,15 @@ Point* p2 = triangle->PointCW(point); Orientation o2 = Orient2d(eq, *p2, ep); if (o2 == COLLINEAR) { - if( triangle->Contains(&eq, p2)) { - triangle->MarkConstrainedEdge(&eq, p2 ); + if (triangle->Contains(&eq, p2)) { + triangle->MarkConstrainedEdge(&eq, p2); // We are modifying the constraint maybe it would be better to // not change the given constraint and just keep a variable for the new constraint tcx.edge_event.constrained_edge->q = p2; - triangle = &triangle->NeighborAcross(point); - EdgeEvent( tcx, ep, *p2, triangle, *p2 ); + triangle = triangle->NeighborAcross(point); + EdgeEvent(tcx, ep, *p2, triangle, *p2); } else { - std::runtime_error("EdgeEvent - collinear points not supported"); - throw(0); - //assert(0); + throw std::runtime_error("EdgeEvent - collinear points not supported"); } return; } @@ -151,12 +160,13 @@ // that will cross edge if (o1 == CW) { triangle = triangle->NeighborCCW(point); - } else{ + } else { triangle = triangle->NeighborCW(point); } EdgeEvent(tcx, ep, eq, triangle, point); } else { // This triangle crosses constraint so lets flippin start! + assert(triangle); FlipEdgeEvent(tcx, ep, eq, triangle, point); } } @@ -217,7 +227,6 @@ if (!Legalize(tcx, *triangle)) { tcx.MapTriangleToNodes(*triangle); } - } void Sweep::FillAdvancingFront(SweepContext& tcx, Node& n) @@ -226,7 +235,7 @@ // Fill right holes Node* node = n.next; - while (node->next) { + while (node && node->next) { // if HoleAngle exceeds 90 degrees then break. if (LargeHole_DontFill(node)) break; Fill(tcx, *node); @@ -236,7 +245,7 @@ // Fill left holes node = n.prev; - while (node->prev) { + while (node && node->prev) { // if HoleAngle exceeds 90 degrees then break. if (LargeHole_DontFill(node)) break; Fill(tcx, *node); @@ -263,12 +272,12 @@ // Check additional points on front. const Node* next2Node = nextNode->next; // "..Plus.." because only want angles on same side as point being added. - if ((next2Node != NULL) && !AngleExceedsPlus90DegreesOrIsNegative(node->point, next2Node->point, prevNode->point)) + if ((next2Node != nullptr) && !AngleExceedsPlus90DegreesOrIsNegative(node->point, next2Node->point, prevNode->point)) return false; const Node* prev2Node = prevNode->prev; // "..Plus.." because only want angles on same side as point being added. - if ((prev2Node != NULL) && !AngleExceedsPlus90DegreesOrIsNegative(node->point, nextNode->point, prev2Node->point)) + if ((prev2Node != nullptr) && !AngleExceedsPlus90DegreesOrIsNegative(node->point, nextNode->point, prev2Node->point)) return false; return true; @@ -295,7 +304,7 @@ */ const double px = origin->x; const double py = origin->y; - const double ax = pa->x- px; + const double ax = pa->x - px; const double ay = pa->y - py; const double bx = pb->x - px; const double by = pb->y - py; @@ -588,7 +597,7 @@ if (Orient2d(*node.point, *node.next->point, *node.next->next->point) == CCW) { // Concave FillRightConcaveEdgeEvent(tcx, edge, node); - } else{ + } else { // Convex FillRightConvexEdgeEvent(tcx, edge, node); // Retry this one @@ -612,7 +621,6 @@ } } } - } void Sweep::FillRightConvexEdgeEvent(SweepContext& tcx, Edge* edge, Node& node) @@ -621,13 +629,13 @@ if (Orient2d(*node.next->point, *node.next->next->point, *node.next->next->next->point) == CCW) { // Concave FillRightConcaveEdgeEvent(tcx, edge, *node.next); - } else{ + } else { // Convex // Next above or below edge? if (Orient2d(*edge->q, *node.next->next->point, *edge->p) == CCW) { // Below FillRightConvexEdgeEvent(tcx, edge, *node.next); - } else{ + } else { // Above } } @@ -666,13 +674,13 @@ if (Orient2d(*node.prev->point, *node.prev->prev->point, *node.prev->prev->prev->point) == CW) { // Concave FillLeftConcaveEdgeEvent(tcx, edge, *node.prev); - } else{ + } else { // Convex // Next above or below edge? if (Orient2d(*edge->q, *node.prev->prev->point, *edge->p) == CW) { // Below FillLeftConvexEdgeEvent(tcx, edge, *node.prev); - } else{ + } else { // Above } } @@ -688,17 +696,22 @@ if (Orient2d(*node.point, *node.prev->point, *node.prev->prev->point) == CW) { // Next is concave FillLeftConcaveEdgeEvent(tcx, edge, node); - } else{ + } else { // Next is convex } } } - } void Sweep::FlipEdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle* t, Point& p) { - Triangle& ot = t->NeighborAcross(p); + assert(t); + Triangle* ot_ptr = t->NeighborAcross(p); + if (ot_ptr == nullptr) + { + throw std::runtime_error("FlipEdgeEvent - null neighbor across"); + } + Triangle& ot = *ot_ptr; Point& op = *ot.OppositePoint(*t, p); if (InScanArea(p, *t->PointCCW(p), *t->PointCW(p), op)) { @@ -764,10 +777,26 @@ void Sweep::FlipScanEdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle& flip_triangle, Triangle& t, Point& p) { - Triangle& ot = t.NeighborAcross(p); - Point& op = *ot.OppositePoint(t, p); + Triangle* ot_ptr = t.NeighborAcross(p); + if (ot_ptr == nullptr) { + throw std::runtime_error("FlipScanEdgeEvent - null neighbor across"); + } + + Point* op_ptr = ot_ptr->OppositePoint(t, p); + if (op_ptr == nullptr) { + throw std::runtime_error("FlipScanEdgeEvent - null opposing point"); + } - if (InScanArea(eq, *flip_triangle.PointCCW(eq), *flip_triangle.PointCW(eq), op)) { + Point* p1 = flip_triangle.PointCCW(eq); + Point* p2 = flip_triangle.PointCW(eq); + if (p1 == nullptr || p2 == nullptr) { + throw std::runtime_error("FlipScanEdgeEvent - null on either of points"); + } + + Triangle& ot = *ot_ptr; + Point& op = *op_ptr; + + if (InScanArea(eq, *p1, *p2, op)) { // flip with new edge op->eq FlipEdgeEvent(tcx, eq, op, &ot, op); // TODO: Actually I just figured out that it should be possible to @@ -777,7 +806,7 @@ // also need to set a new flip_triangle first // Turns out at first glance that this is somewhat complicated // so it will have to wait. - } else{ + } else { Point& newP = NextFlipPoint(ep, eq, ot, op); FlipScanEdgeEvent(tcx, ep, eq, flip_triangle, ot, newP); } @@ -792,5 +821,4 @@ } -} - +} // namespace p2t diff -Nru therion-6.0.4/extern/poly2tri/sweep/sweep_context.cc therion-6.0.5/extern/poly2tri/sweep/sweep_context.cc --- therion-6.0.4/extern/poly2tri/sweep/sweep_context.cc 2021-11-28 12:07:59.000000000 +0000 +++ therion-6.0.5/extern/poly2tri/sweep/sweep_context.cc 2022-02-20 13:23:28.000000000 +0000 @@ -1,6 +1,6 @@ /* - * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors - * http://code.google.com/p/poly2tri/ + * Poly2Tri Copyright (c) 2009-2018, Poly2Tri Contributors + * https://github.com/jhasse/poly2tri * * All rights reserved. * @@ -35,12 +35,12 @@ namespace p2t { SweepContext::SweepContext(const std::vector& polyline) : points_(polyline), - front_(0), - head_(0), - tail_(0), - af_head_(0), - af_middle_(0), - af_tail_(0) + front_(nullptr), + head_(nullptr), + tail_(nullptr), + af_head_(nullptr), + af_middle_(nullptr), + af_tail_(nullptr) { InitEdges(points_); } @@ -87,8 +87,8 @@ double dx = kAlpha * (xmax - xmin); double dy = kAlpha * (ymax - ymin); - head_ = new Point(xmax + dx, ymin - dy); - tail_ = new Point(xmin - dx, ymin - dy); + head_ = new Point(xmin - dx, ymin - dy); + tail_ = new Point(xmax + dx, ymin - dy); // Sort points along y-axis std::sort(points_.begin(), points_.end(), cmp); @@ -114,18 +114,17 @@ map_.push_back(triangle); } -Node& SweepContext::LocateNode(const Point& point) +Node* SweepContext::LocateNode(const Point& point) { // TODO implement search tree - return *front_->LocateNode(point.x); + return front_->LocateNode(point.x); } -void SweepContext::CreateAdvancingFront(const std::vector& nodes) +void SweepContext::CreateAdvancingFront() { - (void) nodes; // Initial triangle - Triangle* triangle = new Triangle(*points_[0], *tail_, *head_); + Triangle* triangle = new Triangle(*points_[0], *head_, *tail_); map_.push_back(triangle); @@ -172,7 +171,7 @@ Triangle *t = triangles.back(); triangles.pop_back(); - if (t != NULL && !t->IsInterior()) { + if (t != nullptr && !t->IsInterior()) { t->IsInterior(true); triangles_.push_back(t); for (int i = 0; i < 3; i++) { @@ -208,4 +207,4 @@ } -} +} // namespace p2t diff -Nru therion-6.0.4/extern/poly2tri/sweep/sweep_context.h therion-6.0.5/extern/poly2tri/sweep/sweep_context.h --- therion-6.0.4/extern/poly2tri/sweep/sweep_context.h 2021-11-28 12:07:59.000000000 +0000 +++ therion-6.0.5/extern/poly2tri/sweep/sweep_context.h 2022-02-20 13:23:28.000000000 +0000 @@ -1,6 +1,6 @@ /* - * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors - * http://code.google.com/p/poly2tri/ + * Poly2Tri Copyright (c) 2009-2018, Poly2Tri Contributors + * https://github.com/jhasse/poly2tri * * All rights reserved. * @@ -66,11 +66,11 @@ size_t point_count() const; -Node& LocateNode(const Point& point); +Node* LocateNode(const Point& point); void RemoveNode(Node* node); -void CreateAdvancingFront(const std::vector& nodes); +void CreateAdvancingFront(); /// Try to map a node to all sides of this triangle that don't have a neighbor void MapTriangleToNodes(Triangle& t); diff -Nru therion-6.0.4/extern/poly2tri/sweep/sweep.h therion-6.0.5/extern/poly2tri/sweep/sweep.h --- therion-6.0.4/extern/poly2tri/sweep/sweep.h 2021-11-28 12:07:59.000000000 +0000 +++ therion-6.0.5/extern/poly2tri/sweep/sweep.h 2022-02-20 13:23:28.000000000 +0000 @@ -1,6 +1,6 @@ /* - * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors - * http://code.google.com/p/poly2tri/ + * Poly2Tri Copyright (c) 2009-2018, Poly2Tri Contributors + * https://github.com/jhasse/poly2tri * * All rights reserved. * @@ -33,7 +33,7 @@ * Zalik, B.(2008)'Sweep-line algorithm for constrained Delaunay triangulation', * International Journal of Geographical Information Science * - * "FlipScan" Constrained Edge Algorithm invented by Thomas ?hl?n, thahlen@gmail.com + * "FlipScan" Constrained Edge Algorithm invented by Thomas hln, thahlen@gmail.com */ #ifndef SWEEP_H @@ -282,4 +282,4 @@ } -#endif \ No newline at end of file +#endif diff -Nru therion-6.0.4/.github/workflows/cmake.yml therion-6.0.5/.github/workflows/cmake.yml --- therion-6.0.4/.github/workflows/cmake.yml 2021-11-28 12:07:59.000000000 +0000 +++ therion-6.0.5/.github/workflows/cmake.yml 2022-02-20 13:23:28.000000000 +0000 @@ -75,6 +75,7 @@ install: make git mingw-w64-${{ matrix.config.arch }}-cmake mingw-w64-${{ matrix.config.arch }}-proj mingw-w64-${{ matrix.config.arch }}-shapelib mingw-w64-${{ matrix.config.arch }}-vtk mingw-w64-${{ matrix.config.arch }}-wxWidgets mingw-w64-${{ matrix.config.arch }}-gcc mingw-w64-${{ matrix.config.arch }}-make mingw-w64-${{ matrix.config.arch }}-bwidget mingw-w64-${{ matrix.config.arch }}-fmt mingw-w64-${{ matrix.config.arch }}-catch - run: mkdir build && cd build && cmake -G "MSYS Makefiles" -DCMAKE_CXX_FLAGS="-Werror" -DUSE_BUNDLED_SHAPELIB=OFF -DUSE_BUNDLED_CATCH2=OFF -DUSE_BUNDLED_FMT=OFF -DBUILD_THBOOK=OFF .. - run: cmake --build build -t therion loch utest -- -j 4 + - run: cmake --build build -t deploy -- -j 4 MXE: runs-on: ${{ matrix.os }} diff -Nru therion-6.0.4/.github/workflows/installer.yaml therion-6.0.5/.github/workflows/installer.yaml --- therion-6.0.4/.github/workflows/installer.yaml 2021-11-28 12:07:59.000000000 +0000 +++ therion-6.0.5/.github/workflows/installer.yaml 2022-02-20 13:23:28.000000000 +0000 @@ -1,12 +1,14 @@ name: Installer on: push jobs: - Win32_installer: + Win32_installer_MXE: runs-on: ubuntu-20.04 outputs: THID: ${{ steps.build.outputs.THID_out }} git_branch: ${{ steps.build.outputs.git_branch }} rel_notes: ${{ steps.build.outputs.rel_notes }} + env: + THDIR: /home/runner/work/therion steps: - uses: actions/checkout@v2 with: @@ -26,7 +28,7 @@ run: | export PATH=/usr/lib/mxe/usr/bin:$PATH mkdir -p $HOME/.wine/drive_c/windows - echo -e "mpost-path /home/runner/work/therion/therion-batteries/bin/win32/mpost.exe\npdftex-path /home/runner/work/therion/therion-batteries/bin/win32/pdftex.exe\nidentify-path /home/runner/work/therion/therion-batteries/bin/identify.exe\nconvert-path /home/runner/work/therion/therion-batteries/bin/convert.exe\n" > $HOME/.wine/drive_c/windows/therion.ini + echo -e "mpost-path ${THDIR}/therion-batteries/bin/win32/mpost.exe\npdftex-path ${THDIR}/therion-batteries/bin/win32/pdftex.exe\nidentify-path ${THDIR}/therion-batteries/bin/identify.exe\nconvert-path ${THDIR}/therion-batteries/bin/convert.exe\n" > $HOME/.wine/drive_c/windows/therion.ini wget -qO - https://github.com/therion/therion-batteries/archive/master.tar.gz | tar -xz && mv therion-batteries-master ../therion-batteries if ${{startsWith(github.ref, 'refs/tags/v')}}; then THID=${GITHUB_REF##*/}; else THID=$(git rev-parse --short HEAD); fi echo "::set-output name=THID_out::$THID" @@ -54,10 +56,70 @@ mv thbook/thbook.pdf thbook-$THID.pdf - uses: 'actions/upload-artifact@v2' with: - name: therion-setup-${{ steps.build.outputs.THID_out }} + name: therion-setup-mxe-${{ steps.build.outputs.THID_out }} + path: | + ${{ env.THDIR }}/therion.bin/therion-setup-${{ steps.build.outputs.THID_out }}.exe + ${{ env.THDIR }}/therion.bin/thbook-${{ steps.build.outputs.THID_out }}.pdf + Win32_installer: + runs-on: windows-latest + strategy: + matrix: + config: + - { msystem: MINGW32, arch: i686 } + defaults: + run: + shell: msys2 {0} + outputs: + THID: ${{ steps.build.outputs.THID_out }} + git_branch: ${{ steps.build.outputs.git_branch }} + rel_notes: ${{ steps.build.outputs.rel_notes }} + env: + THDIR: d:/a/therion + steps: + - uses: msys2/setup-msys2@v2 + with: + msystem: ${{ matrix.config.msystem }} + update: true + install: make git mingw-w64-${{ matrix.config.arch }}-cmake mingw-w64-${{ matrix.config.arch }}-proj mingw-w64-${{ matrix.config.arch }}-shapelib mingw-w64-${{ matrix.config.arch }}-vtk mingw-w64-${{ matrix.config.arch }}-wxWidgets mingw-w64-${{ matrix.config.arch }}-gcc mingw-w64-${{ matrix.config.arch }}-make mingw-w64-${{ matrix.config.arch }}-bwidget mingw-w64-${{ matrix.config.arch }}-fmt mingw-w64-${{ matrix.config.arch }}-catch + - name: prevent git EOL conversion + run: git config --global core.autocrlf input + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: build and create the installation package + id: build + run: | + reg add HKCU\\Software\\Therion //v InstallDir //t REG_SZ //d "${THDIR}/therion-batteries" + mkdir -p $HOME/.therion + echo -e "mpost-path ${THDIR}/therion-batteries/bin/win32/mpost.exe\npdftex-path ${THDIR}/therion-batteries/bin/win32/pdftex.exe\nidentify-path ${THDIR}/therion-batteries/bin/identify.exe\nconvert-path ${THDIR}/therion-batteries/bin/convert.exe\n" > $HOME/.therion/therion.ini + wget -qO - https://github.com/therion/therion-batteries/archive/master.tar.gz | tar -xzf - && mv therion-batteries-master ../therion-batteries + if ${{startsWith(github.ref, 'refs/tags/v')}}; then THID=${GITHUB_REF##*/}; else THID=$(git rev-parse --short HEAD); fi + echo "::set-output name=THID_out::$THID" + BRANCH_FULL=$(git branch -r --contains ${{ github.ref }}) + BRANCH=${BRANCH_FULL##*/} + echo "::set-output name=git_branch::$BRANCH" + ./rel_notes.py + REL_NOTES="$( #include #include +#include +//#include #include #ifdef LXMACOSX #include @@ -429,7 +431,6 @@ this->scrapWalls->SetPoints(sWpoints); this->scrapWalls->SetPolys(sWpolys); - // single surface surfaceNpt = 0; lxFileSurface_list::iterator sf_it = this->m_input.m_surfaces.begin(); @@ -565,6 +566,10 @@ #if VTK_MAJOR_VERSION > 5 this->allWalls->RemoveAllInputs(); this->allWalls->AddInputData(this->scrapWallsNormals->GetOutput()); + //vtkMassProperties * mp = vtkMassProperties::New(); + //mp->SetInputConnection(this->scrapWallsNormals->GetOutputPort()); + //mp->Update(); + //printf("Volume: %.1f\n", mp->GetVolumeProjected()); this->allWalls->AddInputData(this->lrudWalls); #else this->allWalls->RemoveAllInputs(); @@ -629,6 +634,21 @@ #endif w->Write(); w->Delete(); +} + + +void lxData::ExportPLY(wxString fileName) +{ + vtkPLYWriter * w = vtkPLYWriter::New(); + w->SetFileName(fileName.mbc_str()); + w->SetFileTypeToBinary(); +#if VTK_MAJOR_VERSION > 5 + w->SetInputConnection(this->allWalls->GetOutputPort()); +#else + w->SetInput(this->allWalls->GetOutput()); +#endif + w->Write(); + w->Delete(); } diff -Nru therion-6.0.4/loch/lxData.h therion-6.0.5/loch/lxData.h --- therion-6.0.4/loch/lxData.h 2021-11-28 12:07:59.000000000 +0000 +++ therion-6.0.5/loch/lxData.h 2022-02-20 13:23:28.000000000 +0000 @@ -143,7 +143,7 @@ void Rebuild(); void InitTextures(); void ExportVTK(wxString fileName); - + void ExportPLY(wxString fileName); void ClearSurveySelection(); void AddSelectedSurvey(size_t id); diff -Nru therion-6.0.4/loch/lxGUI.cxx therion-6.0.5/loch/lxGUI.cxx --- therion-6.0.4/loch/lxGUI.cxx 2021-11-28 12:07:59.000000000 +0000 +++ therion-6.0.5/loch/lxGUI.cxx 2022-02-20 13:23:28.000000000 +0000 @@ -39,6 +39,7 @@ #include "lxSView.h" #include "lxSScene.h" #include "lxSTree.h" +#include "lxSStats.h" #include "lxPres.h" #include "icons/open.xpm" @@ -153,7 +154,7 @@ lxFrame::lxFrame(class lxApp * app, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxFrame(NULL, wxID_ANY, title, pos, size, style), - m_modelSetupDlg(NULL), m_modelSetupDlgOn(false), m_selectionSetupDlg(NULL), m_selectionSetupDlgOn(false), m_presentationDlg(NULL), m_presentationDlgOn(false), + m_modelSetupDlg(NULL), m_statisticsDlg(NULL), m_modelSetupDlgOn(false), m_statisticsDlgOn(false), m_selectionSetupDlg(NULL), m_selectionSetupDlgOn(false), m_presentationDlg(NULL), m_presentationDlgOn(false), m_viewpointSetupDlg(NULL), m_viewpointSetupDlgOn(false) { @@ -314,6 +315,7 @@ winMenu->AppendCheckItem(LXMENU_VIEW_VIEWPOINTSTP, _("&Camera")); winMenu->AppendCheckItem(LXMENU_VIEW_MODELSTP, _("&Scene")); winMenu->AppendCheckItem(LXMENU_VIEW_SELECTIONSTP, _("&Selection")); + winMenu->AppendCheckItem(LXMENU_VIEW_SURVEYSTATS, _("&Survey statistics")); winMenu->AppendCheckItem(LXMENU_VIEW_PRESENTDLG, _("&Presentation")); winMenu->Append(LXMENU_EXPROT, _("&Animation")); winMenu->AppendSeparator(); @@ -351,7 +353,9 @@ this->SetSize(size); this->m_modelSetupDlg = new lxModelSetupDlg(this); + this->m_statisticsDlg = new lxSurveyStatsDlg(this); this->m_modelSetupDlgOn = false; + this->m_statisticsDlgOn = false; this->m_selectionSetupDlg = new lxModelTreeDlg(this); this->m_presentationDlg = new lxPresentDlg(this); @@ -629,7 +633,7 @@ _("Export"), wxEmptyString, wxEmptyString, - _("VTK file (*.vtk)|*.vtk|Loch file (*.lox)|*.lox"), + _("VTK file (*.vtk)|*.vtk|Loch file (*.lox)|*.lox|PLY file (*.ply)|*.ply"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT ); @@ -644,6 +648,9 @@ case 1: this->data->m_input.ExportLOX(dialog.GetPath().mbc_str()); break; + case 2: + this->data->ExportPLY(dialog.GetPath()); + break; } this->canvas->ForceRefresh(); } @@ -717,6 +724,10 @@ this->ToggleModelSetup(); break; + case LXMENU_VIEW_SURVEYSTATS: + this->ToggleSurveyStats(); + break; + case LXMENU_VIEW_SELECTIONSTP: this->ToggleSelectionSetup(); break; @@ -810,6 +821,9 @@ if (this->m_modelSetupDlg != NULL) { this->m_modelSetupDlg->m_toolBoxPosition.Restore(); } + if (this->m_statisticsDlg != NULL) { + this->m_statisticsDlg->m_toolBoxPosition.Restore(); + } if (this->m_selectionSetupDlg != NULL) { this->m_selectionSetupDlg->m_toolBoxPosition.Restore(); } @@ -828,6 +842,9 @@ if (this->m_modelSetupDlg != NULL) { this->m_modelSetupDlg->m_toolBoxPosition.Restore(); } + if (this->m_statisticsDlg != NULL) { + this->m_statisticsDlg->m_toolBoxPosition.Restore(); + } if (this->m_selectionSetupDlg != NULL) { this->m_selectionSetupDlg->m_toolBoxPosition.Restore(); } @@ -845,6 +862,7 @@ this->m_menuBar->Check(LXMENU_VIEW_MODELSTP, this->m_modelSetupDlgOn); this->m_menuBar->Check(LXMENU_VIEW_VIEWPOINTSTP, this->m_viewpointSetupDlgOn); this->m_menuBar->Check(LXMENU_VIEW_SELECTIONSTP, this->m_selectionSetupDlgOn); + this->m_menuBar->Check(LXMENU_VIEW_SURVEYSTATS, this->m_statisticsDlgOn); this->m_menuBar->Check(LXMENU_VIEW_PRESENTDLG, this->m_presentationDlgOn); this->m_toolBar->ToggleTool(LXTB_PERSP, !this->setup->cam_persp); @@ -1008,6 +1026,20 @@ } +void lxFrame::ToggleSurveyStats() +{ + if (this->m_statisticsDlgOn) { + this->m_statisticsDlg->m_toolBoxPosition.Save(); + this->m_statisticsDlg->Show(false); + } else { + this->m_statisticsDlg->m_toolBoxPosition.Restore(); + this->m_statisticsDlg->Show(true); + } + this->m_statisticsDlgOn = !this->m_statisticsDlgOn; + this->UpdateM2TB(); +} + + void lxFrame::ToggleSelectionSetup() { if (this->m_selectionSetupDlgOn) { @@ -1134,6 +1166,7 @@ this->LoadData(this->m_fileName, this->m_fileType); this->m_modelSetupDlg->InitSetup(); this->m_selectionSetupDlg->LoadData(); + this->m_statisticsDlg->LoadData(); } diff -Nru therion-6.0.4/loch/lxGUI.h therion-6.0.5/loch/lxGUI.h --- therion-6.0.4/loch/lxGUI.h 2021-11-28 12:07:59.000000000 +0000 +++ therion-6.0.5/loch/lxGUI.h 2022-02-20 13:23:28.000000000 +0000 @@ -70,6 +70,7 @@ LXMENU_VIEW, LXMENU_VIEW_FULLSCREEN, LXMENU_VIEW_MODELSTP, + LXMENU_VIEW_SURVEYSTATS, LXMENU_VIEW_SELECTIONSTP, LXMENU_VIEW_VIEWPOINTSTP, LXMENU_VIEW_PRESENTDLG, @@ -161,7 +162,8 @@ class lxModelSetupDlg * m_modelSetupDlg; - bool m_modelSetupDlgOn; + class lxSurveyStatsDlg * m_statisticsDlg; + bool m_modelSetupDlgOn, m_statisticsDlgOn; class lxModelTreeDlg * m_selectionSetupDlg; bool m_selectionSetupDlgOn; @@ -208,6 +210,7 @@ void ToggleRotLock(); void ToggleFullScreen(); void ToggleModelSetup(); + void ToggleSurveyStats(); void ToggleSelectionSetup(); void TogglePresentationDlg(); void ToggleViewpointSetup(); diff -Nru therion-6.0.4/loch/lxSStats.cxx therion-6.0.5/loch/lxSStats.cxx --- therion-6.0.4/loch/lxSStats.cxx 1970-01-01 00:00:00.000000000 +0000 +++ therion-6.0.5/loch/lxSStats.cxx 2022-02-20 13:23:28.000000000 +0000 @@ -0,0 +1,124 @@ +// Standard libraries +#ifndef LXDEPCHECK +#include +#include +#include +#endif +//LXDEPCHECK - standard libraries + +#include "lxSStats.h" +#include "lxSetup.h" +#include "lxGUI.h" +#include "lxGLC.h" + +#ifndef LXGNUMSW +#include "loch.xpm" +#endif + +#include + +enum { + lxSS_SURVEY_STATS = 4000, +}; + + +BEGIN_EVENT_TABLE(lxSurveyStatsDlg, wxMiniFrame) + EVT_BUTTON(wxID_CLOSE, lxSurveyStatsDlg::OnCommand) + EVT_MOVE(lxSurveyStatsDlg::OnMove) + EVT_CLOSE(lxSurveyStatsDlg::OnClose) +END_EVENT_TABLE() + + +void lxSurveyStatsDlg::OnCommand(wxCommandEvent& event) +{ + switch (event.GetId()) { + case wxID_CLOSE: + this->m_mainFrame->ToggleSurveyStats(); + break; + } +} + + + +void lxSurveyStatsDlg::OnClose(wxCloseEvent& WXUNUSED(event)) +{ + this->m_mainFrame->ToggleSurveyStats(); +} + +void lxSurveyStatsDlg::OnMove(wxMoveEvent& WXUNUSED(event)) +{ + this->m_toolBoxPosition.Save(); +} + + +lxSurveyStatsDlg::lxSurveyStatsDlg(wxWindow *parent) + : wxMiniFrame(parent, wxID_ANY, _(" Survey statistics"),wxDefaultPosition, wxDefaultSize, (wxSYSTEM_MENU | wxCAPTION | wxCLOSE_BOX | wxRESIZE_BORDER) & (~(wxMINIMIZE_BOX | wxMAXIMIZE_BOX))) +{ + + this->m_toolBoxPosition.Init(this, parent, 0, 8, 8); + +#ifdef LXGNUMSW + this->SetIcon(wxIcon(_T("LOCHICON"))); +#else + this->SetIcon(wxIcon(loch_xpm)); +#endif + + this->m_mainFrame = (lxFrame *) parent; + + wxBoxSizer * sizerFrame = new wxBoxSizer(wxVERTICAL); + wxBoxSizer * sizerTop = new wxBoxSizer(wxVERTICAL); + + lxPanel = new wxPanel(this, wxID_ANY); + + this->m_statsControl = new wxTextCtrl(lxPanel,wxID_ANY, wxEmptyString, wxDefaultPosition,wxDefaultSize,wxTE_MULTILINE | wxTE_READONLY | wxHSCROLL); + + wxBoxSizer * lxBoxSizer = new wxBoxSizer(wxHORIZONTAL); + lxBoxSizer->Add(new wxButton(lxPanel, wxID_CLOSE, _("Close")), 0, wxALIGN_CENTER , lxBORDER); + + + sizerTop->Add( this->m_statsControl, + 1, wxALL | wxEXPAND, lxBORDER); + sizerTop->Add( + lxBoxSizer, + 0, wxALIGN_RIGHT | lxNOTTOP, lxBORDER); + + lxPanel->SetSizer(sizerTop); + sizerTop->Fit(lxPanel); + + sizerFrame->Add(lxPanel, 1, wxEXPAND | wxALL); + + this->SetSizer(sizerFrame); + sizerFrame->SetSizeHints(this); + sizerFrame->Fit(this); + + wxSize mfs = this->m_mainFrame->GetSize(); + this->SetSize(mfs.GetWidth() / 4, mfs.GetHeight() / 2); + +} + + +void lxSurveyStatsDlg::LoadData() +{ + lxData * data = this->m_mainFrame->data; + vtkMassProperties * smp = vtkMassProperties::New(); + smp->SetInputConnection(data->scrapWallsNormals->GetOutputPort()); + smp->Update(); + + vtkMassProperties * emp = vtkMassProperties::New(); + emp->SetInputData(data->lrudWalls); + emp->Update(); + + double cf = 1.0; + wxString cfu = _("cbm"); + if (this->m_mainFrame->m_iniUnits == LXUNITS_IMPERIAL) { + cf = 35.314667; + cfu = _("cft"); + } + + this->m_statsControl->Clear(); + this->m_statsControl->AppendText(wxString::Format(_("LRUD envelope volume: %.1f %s\n"), cf * emp->GetVolumeProjected(), cfu)); + this->m_statsControl->AppendText(wxString::Format(_("Maps 3d volume: %.1f %s\n"), cf * smp->GetVolumeProjected(), cfu)); +} + + + diff -Nru therion-6.0.4/loch/lxSStats.h therion-6.0.5/loch/lxSStats.h --- therion-6.0.4/loch/lxSStats.h 1970-01-01 00:00:00.000000000 +0000 +++ therion-6.0.5/loch/lxSStats.h 2022-02-20 13:23:28.000000000 +0000 @@ -0,0 +1,50 @@ +/** + * @file lxSStats.h + * Survey statistics. + */ + +/* Copyright (C) 2022 Stacho Mudrak + * + * $Date: $ + * $RCSfile: $ + * $Revision: $ + */ + +#ifndef lxSStats_h +#define lxSStats_h + + +// Standard libraries +#ifndef LXDEPCHECK +#include +#include +#endif +//LXDEPCHECK - standard libraries + + +#include "lxWX.h" + + + +class lxSurveyStatsDlg : public wxMiniFrame +{ +public: + + lxTBoxPos m_toolBoxPosition; + class lxFrame * m_mainFrame; + wxTextCtrl * m_statsControl; + + lxSurveyStatsDlg(wxWindow *parent); + void LoadData(); + + void OnCommand(wxCommandEvent& event); + void OnClose(wxCloseEvent& event); + void OnMove(wxMoveEvent& event); + +private: + DECLARE_EVENT_TABLE() +}; + + +#endif + diff -Nru therion-6.0.4/loch/Makefile therion-6.0.5/loch/Makefile --- therion-6.0.4/loch/Makefile 2021-11-28 12:07:59.000000000 +0000 +++ therion-6.0.5/loch/Makefile 2022-02-20 13:23:28.000000000 +0000 @@ -13,7 +13,7 @@ lxTR.o lxOGLFT.o lxSetup.o lxRender.o lxWX.o \ lxImgIO.o lxLRUD.o lxFile.o lxSTree.o \ lxData.o lxMath.o lxSView.o lxSScene.o \ - lxGUI.o lxGLC.o lxOptDlg.o lxAboutDlg.o lxPres.o \ + lxGUI.o lxGLC.o lxOptDlg.o lxAboutDlg.o lxPres.o lxSStats.o \ img.o EXT = @@ -43,6 +43,7 @@ -lvtkCommonExecutionModel$(VTKLIBSUFFIX) \ -lvtkCommonDataModel$(VTKLIBSUFFIX) \ -lvtkCommonCore$(VTKLIBSUFFIX) \ + -lvtkIOPLY$(VTKLIBSUFFIX) \ -lvtkFiltersCore$(VTKLIBSUFFIX) \ -lvtkFiltersHybrid$(VTKLIBSUFFIX) \ -lvtkIOLegacy$(VTKLIBSUFFIX) \ @@ -67,7 +68,7 @@ ##CC = gcc ##POBJECTS = lxR2P.o ##ifeq ($(VTKV6),1) -##VTKLIBS = -lvtkCommonExecutionModel -lvtkCommonDataModel -lvtkCommonCore -lvtkFiltersCore -lvtkFiltersHybrid -lvtkIOLegacy -lfreetype -lpng -ljpeg +##VTKLIBS = -lvtkCommonExecutionModel -lvtkCommonDataModel -lvtkCommonCore -lvtkIOPLY -lvtkFiltersCore -lvtkFiltersHybrid -lvtkIOLegacy -lfreetype -lpng -ljpeg ##else ##VTKLIBS = -lvtkHybrid -lvtkImaging -lvtkIO -lvtkGraphics -lvtkFiltering -lvtkCommon -lfreetype ##endif @@ -121,7 +122,7 @@ ##VTKVERSION = 8.2 ##VTKPATH = /usr/lib/mxe/usr/$(CROSS2)/include/vtk-$(VTKVERSION) ##VTKLIBPATH = /usr/lib/mxe/usr/$(CROSS2)/lib -##VTKLIBS = -lvtkCommonExecutionModel-$(VTKVERSION) -lvtkCommonDataModel-$(VTKVERSION) \ +##VTKLIBS = -lvtkCommonExecutionModel-$(VTKVERSION) -lvtkCommonDataModel-$(VTKVERSION) -lvtkIOPLY-$(VTKVERSION)\ ## -lvtkFiltersCore-$(VTKVERSION) -lvtkFiltersHybrid-$(VTKVERSION) \ ## -lvtkIOLegacy-$(VTKVERSION) -lvtkCommonCore-$(VTKVERSION) -lvtkIOCore-$(VTKVERSION) \ ## -lvtkCommonTransforms-$(VTKVERSION) -lvtkCommonMisc-$(VTKVERSION) -lvtkCommonMath-$(VTKVERSION) -lvtkCommonSystem-$(VTKVERSION) \ diff -Nru therion-6.0.4/test_proj.sh therion-6.0.5/test_proj.sh --- therion-6.0.4/test_proj.sh 2021-11-28 12:07:59.000000000 +0000 +++ therion-6.0.5/test_proj.sh 2022-02-20 13:23:28.000000000 +0000 @@ -12,7 +12,7 @@ set -e SRCPATH=${1:-.} -PROJVER=${2:-4.9.3 5.1.0 5.2.0 6.2.1 6.3.2 7.0.0 7.2.1 8.0.0 8.2.0} +PROJVER=${2:-4.9.3 5.1.0 5.2.0 6.2.1 6.3.2 7.0.0 7.2.1 8.0.0 8.2.1} PREFIX=$HOME/tmp/ThProj_test URL=https://download.osgeo.org/proj/proj diff -Nru therion-6.0.4/thbook/ch02.tex therion-6.0.5/thbook/ch02.tex --- therion-6.0.4/thbook/ch02.tex 2021-11-28 12:07:59.000000000 +0000 +++ therion-6.0.5/thbook/ch02.tex 2022-02-20 13:23:28.000000000 +0000 @@ -394,7 +394,7 @@ * |team []| = a survey team member. The first argument is his/her name, the others describe the roles of the person in the team (optional---currently not used). The following role keywords are - supported: station, length, tape, [back]compass, [back]bearing, [back]clino, + supported: station, [back]length, [back]tape, [back]compass, [back]bearing, [back]clino, [back]gradient, counter, depth, station, position, notes, pictures, pics, instruments (insts), assistant (dog). * |explo-team | = a discovery team member. @@ -480,7 +480,7 @@ * |equate | = set points that are equivalent * |data