#define GEOGRAM_PSM #ifndef GEO_STATIC_LIBS #define GEO_DYNAMIC_LIBS #endif /* * Copyright (c) 2000-2022 Inria * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the ALICE Project-Team nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * Contact: Bruno Levy * * https://www.inria.fr/fr/bruno-levy * * Inria, * Domaine de Voluceau, * 78150 Le Chesnay - Rocquencourt * FRANCE * */ /* * This file is a PSM (pluggable software module) * generated from the distribution of Geogram. * * See Geogram documentation on: * http://alice.loria.fr/software/geogram/doc/html/index.html * * See documentation of the functions bundled in this PSM on: * http://alice.loria.fr/software/geogram/doc/html/namespaceGEO_1_1PCK.html */ /******* extracted from ../api/defs.h *******/ #ifndef GEOGRAM_API_DEFS #define GEOGRAM_API_DEFS /* * Deactivate warnings about documentation * We do that, because CLANG's doxygen parser does not know * some doxygen commands that we use (retval, copydoc) and * generates many warnings for them... */ #if defined(__clang__) #pragma clang diagnostic ignored "-Wunknown-pragmas" #pragma clang diagnostic ignored "-Wdocumentation-unknown-command" #endif #if defined(GEO_DYNAMIC_LIBS) #if defined(_MSC_VER) #define GEO_IMPORT __declspec(dllimport) #define GEO_EXPORT __declspec(dllexport) #elif defined(__GNUC__) #define GEO_IMPORT #define GEO_EXPORT __attribute__ ((visibility("default"))) #else #define GEO_IMPORT #define GEO_EXPORT #endif #else #define GEO_IMPORT #define GEO_EXPORT #endif #ifdef geogram_EXPORTS #define GEOGRAM_API GEO_EXPORT #else #define GEOGRAM_API GEO_IMPORT #endif #define NO_GEOGRAM_API typedef int GeoMesh; typedef unsigned char geo_coord_index_t; /* * If GARGANTUA is defined, then geogram is compiled * with 64 bit indices. */ #ifdef GARGANTUA #include typedef uint64_t geo_index_t; typedef int64_t geo_signed_index_t; #else typedef unsigned int geo_index_t; typedef int geo_signed_index_t; #endif typedef double geo_coord_t; typedef int geo_boolean; enum { GEO_FALSE = 0, GEO_TRUE = 1 }; #endif /******* extracted from ../basic/common.h *******/ #ifndef GEOGRAM_BASIC_COMMON #define GEOGRAM_BASIC_COMMON // iostream should be included before anything else, // otherwise 'cin', 'cout' and 'cerr' will be uninitialized. #include namespace GEO { enum { GEOGRAM_NO_HANDLER = 0, GEOGRAM_INSTALL_HANDLERS = 1 }; void GEOGRAM_API initialize(int flags = GEOGRAM_INSTALL_HANDLERS); void GEOGRAM_API terminate(); } #if (defined(NDEBUG) || defined(GEOGRAM_PSM)) && !defined(GEOGRAM_PSM_DEBUG) #undef GEO_DEBUG #undef GEO_PARANOID #else #define GEO_DEBUG #define GEO_PARANOID #endif // =============================== LINUX defines =========================== #if defined(__ANDROID__) #define GEO_OS_ANDROID #endif #if defined(__linux__) #define GEO_OS_LINUX #define GEO_OS_UNIX #ifndef GEO_OS_ANDROID #define GEO_OS_X11 #endif #if defined(_OPENMP) # define GEO_OPENMP #endif #if defined(__INTEL_COMPILER) # define GEO_COMPILER_INTEL #elif defined(__clang__) # define GEO_COMPILER_CLANG #elif defined(__GNUC__) # define GEO_COMPILER_GCC #else # error "Unsupported compiler" #endif // The following works on GCC and ICC #if defined(__x86_64) # define GEO_ARCH_64 # define GEO_PROCESSOR_X86 #else # define GEO_ARCH_32 #endif // =============================== WINDOWS defines ========================= #elif defined(_WIN32) || defined(_WIN64) #define GEO_OS_WINDOWS #define GEO_PROCESSOR_X86 #if defined(_OPENMP) # define GEO_OPENMP #endif #if defined(_MSC_VER) # define GEO_COMPILER_MSVC #elif defined(__MINGW32__) || defined(__MINGW64__) # define GEO_COMPILER_MINGW #endif #if defined(_WIN64) # define GEO_ARCH_64 #else # define GEO_ARCH_32 #endif // =============================== APPLE defines =========================== #elif defined(__APPLE__) #define GEO_OS_APPLE #define GEO_OS_UNIX #if defined(_OPENMP) # define GEO_OPENMP #endif #if defined(__clang__) # define GEO_COMPILER_CLANG #elif defined(__GNUC__) # define GEO_COMPILER_GCC #else # error "Unsupported compiler" #endif #if defined(__x86_64) || defined(__ppc64__) || defined(__arm64__) || defined(__aarch64__) || (defined(__riscv) && __riscv_xlen == 64) # define GEO_ARCH_64 #else # define GEO_ARCH_32 #endif // =============================== Emscripten defines ====================== #elif defined(__EMSCRIPTEN__) #define GEO_OS_UNIX #define GEO_OS_LINUX #define GEO_OS_EMSCRIPTEN #define GEO_ARCH_64 #define GEO_COMPILER_EMSCRIPTEN // =============================== Unsupported ============================= #else #error "Unsupported operating system" #endif #if defined(GEO_COMPILER_GCC) || \ defined(GEO_COMPILER_CLANG) || \ defined(GEO_COMPILER_MINGW) || \ defined(GEO_COMPILER_EMSCRIPTEN) #define GEO_COMPILER_GCC_FAMILY #endif #ifdef DOXYGEN_ONLY // Keep doxygen happy #define GEO_OS_WINDOWS #define GEO_OS_APPLE #define GEO_OS_ANDROID #define GEO_ARCH_32 #define GEO_COMPILER_INTEL #define GEO_COMPILER_MSVC #endif #define CPP_CONCAT_(A, B) A ## B #define CPP_CONCAT(A, B) CPP_CONCAT_(A, B) #if defined(GOMGEN) #define GEO_NORETURN #elif defined(GEO_COMPILER_GCC_FAMILY) || \ defined(GEO_COMPILER_INTEL) #define GEO_NORETURN __attribute__((noreturn)) #else #define GEO_NORETURN #endif #if defined(GOMGEN) #define GEO_NORETURN_DECL #elif defined(GEO_COMPILER_MSVC) #define GEO_NORETURN_DECL __declspec(noreturn) #else #define GEO_NORETURN_DECL #endif #if defined(GEO_COMPILER_CLANG) || defined(GEO_COMPILER_EMSCRIPTEN) #if __has_feature(cxx_noexcept) #define GEO_NOEXCEPT noexcept #endif #endif // For Graphite GOM generator (swig is confused by throw() specifier) #ifdef GOMGEN #define GEO_NOEXCEPT #endif #ifndef GEO_NOEXCEPT #define GEO_NOEXCEPT throw() #endif #define FOR(I,UPPERBND) for(index_t I = 0; I inline void geo_argused(const T&) { } } #endif /******* extracted from ../basic/numeric.h *******/ #ifndef GEOGRAM_BASIC_NUMERIC #define GEOGRAM_BASIC_NUMERIC #include #include #include #include // for std::min / std::max #include #include #ifndef M_PI #define M_PI 3.14159265358979323846 #endif namespace GEO { enum Sign { NEGATIVE = -1, ZERO = 0, POSITIVE = 1 }; template inline Sign geo_sgn(const T& x) { return (x > 0) ? POSITIVE : ( (x < 0) ? NEGATIVE : ZERO ); } template inline Sign geo_cmp(const T& a, const T& b) { return Sign((a > b) * POSITIVE + (a < b) * NEGATIVE); } namespace Numeric { typedef void* pointer; typedef int8_t int8; typedef int16_t int16; typedef int32_t int32; typedef int64_t int64; typedef uint8_t uint8; typedef uint16_t uint16; typedef uint32_t uint32; typedef uint64_t uint64; typedef float float32; typedef double float64; inline float32 max_float32() { return std::numeric_limits::max(); } inline float32 min_float32() { // Note: numeric_limits<>::min() is not // what we want (it returns the smallest // positive non-denormal). return -max_float32(); } inline float64 max_float64() { return std::numeric_limits::max(); } inline float64 min_float64() { // Note: numeric_limits<>::min() is not // what we want (it returns the smallest // positive non-denormal). return -max_float64(); } bool GEOGRAM_API is_nan(float32 x); bool GEOGRAM_API is_nan(float64 x); void GEOGRAM_API random_reset(); int32 GEOGRAM_API random_int32(); float32 GEOGRAM_API random_float32(); float64 GEOGRAM_API random_float64(); template struct LimitsHelper : std::numeric_limits { }; template struct LimitsHelper : std::numeric_limits { static const size_t size = sizeof(T); static const size_t numbits = 8 * sizeof(T); }; template struct Limits : LimitsHelper::is_specialized> { }; template inline void optimize_number_representation(T& x) { geo_argused(x); } template inline Sign ratio_compare( const T& a_num, const T& a_denom, const T& b_num, const T& b_denom ) { if(a_denom == b_denom) { return Sign(geo_cmp(a_num,b_num)*geo_sgn(a_denom)); } return Sign( geo_cmp(a_num*b_denom, b_num*a_denom) * geo_sgn(a_denom) * geo_sgn(b_denom) ); } } template inline T geo_sqr(T x) { return x * x; } template inline void geo_clamp(T& x, T min, T max) { if(x < min) { x = min; } else if(x > max) { x = max; } } typedef geo_index_t index_t; inline index_t max_index_t() { return std::numeric_limits::max(); } typedef geo_signed_index_t signed_index_t; inline signed_index_t max_signed_index_t() { return std::numeric_limits::max(); } inline signed_index_t min_signed_index_t() { return std::numeric_limits::min(); } typedef geo_coord_index_t coord_index_t; inline double round(double x) { return ((x - floor(x)) > 0.5 ? ceil(x) : floor(x)); } static constexpr index_t NO_INDEX = index_t(-1); } #endif /******* extracted from ../basic/psm.h *******/ #ifndef GEOGRAM_BASIC_PSM #define GEOGRAM_BASIC_PSM #include #include #include #ifndef GEOGRAM_PSM #define GEOGRAM_PSM #endif #ifndef GEOGRAM_BASIC_ASSERT #define geo_assert(x) assert(x) #define geo_range_assert(x, min_val, max_val) \ assert((x) >= (min_val) && (x) <= (max_val)) #define geo_assert_not_reached assert(0) #ifdef GEO_DEBUG #define geo_debug_assert(x) assert(x) #define geo_debug_range_assert(x, min_val, max_val) \ assert((x) >= (min_val) && (x) <= (max_val)) #else #define geo_debug_assert(x) #define geo_debug_range_assert(x, min_val, max_val) #endif #ifdef GEO_PARANOID #define geo_parano_assert(x) geo_assert(x) #define geo_parano_range_assert(x, min_val, max_val) \ geo_range_assert(x, min_val, max_val) #else #define geo_parano_assert(x) #define geo_parano_range_assert(x, min_val, max_val) #endif #endif #ifndef geo_cite #define geo_cite(x) #endif #ifndef geo_cite_with_info #define geo_cite_with_info(x,y) #endif #ifndef GEOGRAM_BASIC_LOGGER namespace GEO { namespace Logger { inline std::ostream& out(const std::string& name) { return std::cout << " [" << name << "]"; } inline std::ostream& err(const std::string& name) { return std::cerr << "E[" << name << "]"; } inline std::ostream& warn(const std::string& name) { return std::cerr << "W[" << name << "]"; } } } #endif #ifndef FPG_UNCERTAIN_VALUE #define FPG_UNCERTAIN_VALUE 0 #endif #ifndef GEOGRAM_BASIC_THREAD_SYNC #define GEOGRAM_SPINLOCK_INIT 0 namespace GEO { namespace Process { typedef int spinlock; inline void acquire_spinlock(spinlock& x) { // Not implemented yet for PSMs geo_argused(x); geo_assert_not_reached; } inline void release_spinlock(spinlock& x) { // Not implemented yet for PSMs geo_argused(x); geo_assert_not_reached; } } } #endif #define GEOGRAM_WITH_PDEL #endif /******* extracted from ../basic/determinant.h *******/ #ifndef GEOGRAM_BASIC_DETERMINANT #define GEOGRAM_BASIC_DETERMINANT namespace GEO { template inline T det2x2( const T& a11, const T& a12, const T& a21, const T& a22 ) { return a11*a22-a12*a21 ; } template inline T det3x3( const T& a11, const T& a12, const T& a13, const T& a21, const T& a22, const T& a23, const T& a31, const T& a32, const T& a33 ) { return a11*det2x2(a22,a23,a32,a33) -a21*det2x2(a12,a13,a32,a33) +a31*det2x2(a12,a13,a22,a23); } template inline T det4x4( const T& a11, const T& a12, const T& a13, const T& a14, const T& a21, const T& a22, const T& a23, const T& a24, const T& a31, const T& a32, const T& a33, const T& a34, const T& a41, const T& a42, const T& a43, const T& a44 ) { T m12 = a21*a12 - a11*a22; T m13 = a31*a12 - a11*a32; T m14 = a41*a12 - a11*a42; T m23 = a31*a22 - a21*a32; T m24 = a41*a22 - a21*a42; T m34 = a41*a32 - a31*a42; T m123 = m23*a13 - m13*a23 + m12*a33; T m124 = m24*a13 - m14*a23 + m12*a43; T m134 = m34*a13 - m14*a33 + m13*a43; T m234 = m34*a23 - m24*a33 + m23*a43; return (m234*a14 - m134*a24 + m124*a34 - m123*a44); } } #endif /******* extracted from PCK.h *******/ #ifndef GEOGRAM_NUMERICS_PCK #define GEOGRAM_NUMERICS_PCK #include #include #include // Uncomment to get full reporting on predicate statistics // (but has a non-negligible impact on performance) // For instance, Early Universe Reconstruction with 2M points: // with PCK_STATS: 6'36 without PCK_STATS: 3'38 //#define PCK_STATS namespace GEO { namespace PCK { #ifdef PCK_STATS class GEOGRAM_API PredicateStats { public: PredicateStats(const char* name); void log_invoke() { ++invoke_count_; } void log_exact() { ++exact_count_; } void log_SOS() { ++SOS_count_; } void show_stats(); static void show_all_stats(); private: static PredicateStats* first_; PredicateStats* next_; const char* name_; std::atomic invoke_count_; std::atomic exact_count_; std::atomic SOS_count_; }; #else class PredicateStats { public: PredicateStats(const char* name) { geo_argused(name); } void log_invoke() { } void log_exact() { } void log_SOS() { } static void show_all_stats() { Logger::out("Stats") << "Compiled without PCK_STAT (no stats)" << std::endl; } }; #endif #define SOS_result(x) [&]()->Sign { return Sign(x); } template < class POINT, class COMPARE, class FUNC1, class FUNC2, class FUNC3, class FUNC4 > inline Sign SOS( COMPARE compare, const POINT& p1, FUNC1 sos_p1, const POINT& p2, FUNC2 sos_p2, const POINT& p3, FUNC3 sos_p3, const POINT& p4, FUNC4 sos_p4 ) { static constexpr int N = 4; Sign result = ZERO; const POINT* p[N] = {&p1, &p2, &p3, &p4}; std::sort( p, p+N, [compare](const POINT* A, const POINT* B)->bool{ return compare(*A,*B); } ); for(int i=0; i