diff --git a/Duin/Duin.vcxproj b/Duin/Duin.vcxproj
index 561c40e..d2cc9f4 100644
--- a/Duin/Duin.vcxproj
+++ b/Duin/Duin.vcxproj
@@ -79,7 +79,7 @@
dnpch.h
Level3
DN_PLATFORM_WINDOWS;DN_BUILD_DLL;IMGUI_IMPL_OPENGL_LOADER_GLAD;DN_DEBUG;%(PreprocessorDefinitions)
- src;vendor\patches\include;vendor\spdlog\include;vendor\raylib5\include;vendor\raylib5\src;vendor\raylib-cpp\include;vendor\imgui;vendor\rlgui;vendor\entt\single_include;vendor\fmt\include;%(AdditionalIncludeDirectories)
+ src;vendor\patches\include;vendor\spdlog\include;vendor\raylib5\include;vendor\raylib5\src;vendor\raylib-cpp\include;vendor\imgui;vendor\rlgui;vendor\entt\single_include;vendor\fmt\include;vendor\cdt\CDT\include;%(AdditionalIncludeDirectories)
EditAndContinue
Disabled
MultiThreadedDebugDLL
@@ -104,7 +104,7 @@ IF EXIST ..\bin\Debug-windows-x86_64\Duin\Duin.dll\ (xcopy /Q /E /Y /I ..\bin\De
dnpch.h
Level3
DN_PLATFORM_WINDOWS;DN_BUILD_DLL;IMGUI_IMPL_OPENGL_LOADER_GLAD;DN_RELEASE;%(PreprocessorDefinitions)
- src;vendor\patches\include;vendor\spdlog\include;vendor\raylib5\include;vendor\raylib5\src;vendor\raylib-cpp\include;vendor\imgui;vendor\rlgui;vendor\entt\single_include;vendor\fmt\include;%(AdditionalIncludeDirectories)
+ src;vendor\patches\include;vendor\spdlog\include;vendor\raylib5\include;vendor\raylib5\src;vendor\raylib-cpp\include;vendor\imgui;vendor\rlgui;vendor\entt\single_include;vendor\fmt\include;vendor\cdt\CDT\include;%(AdditionalIncludeDirectories)
Full
true
true
@@ -133,7 +133,7 @@ IF EXIST ..\bin\Release-windows-x86_64\Duin\Duin.dll\ (xcopy /Q /E /Y /I ..\bin\
dnpch.h
Level3
DN_PLATFORM_WINDOWS;DN_BUILD_DLL;IMGUI_IMPL_OPENGL_LOADER_GLAD;DN_DIST;%(PreprocessorDefinitions)
- src;vendor\patches\include;vendor\spdlog\include;vendor\raylib5\include;vendor\raylib5\src;vendor\raylib-cpp\include;vendor\imgui;vendor\rlgui;vendor\entt\single_include;vendor\fmt\include;%(AdditionalIncludeDirectories)
+ src;vendor\patches\include;vendor\spdlog\include;vendor\raylib5\include;vendor\raylib5\src;vendor\raylib-cpp\include;vendor\imgui;vendor\rlgui;vendor\entt\single_include;vendor\fmt\include;vendor\cdt\CDT\include;%(AdditionalIncludeDirectories)
Full
true
true
@@ -160,6 +160,7 @@ IF EXIST ..\bin\Dist-windows-x86_64\Duin\Duin.dll\ (xcopy /Q /E /Y /I ..\bin\Dis
+
@@ -176,6 +177,7 @@ IF EXIST ..\bin\Dist-windows-x86_64\Duin\Duin.dll\ (xcopy /Q /E /Y /I ..\bin\Dis
+
@@ -198,6 +200,7 @@ IF EXIST ..\bin\Dist-windows-x86_64\Duin\Duin.dll\ (xcopy /Q /E /Y /I ..\bin\Dis
+
diff --git a/Duin/Duin.vcxproj.filters b/Duin/Duin.vcxproj.filters
index 0cdeca3..8a1136a 100644
--- a/Duin/Duin.vcxproj.filters
+++ b/Duin/Duin.vcxproj.filters
@@ -100,6 +100,9 @@
Duin\Core
+
+ Duin\Core\Structures
+
Duin\Core\Structures
@@ -155,6 +158,7 @@
Duin\Object
+
@@ -215,5 +219,6 @@
Duin\Object
+
\ No newline at end of file
diff --git a/Duin/src/Duin.h b/Duin/src/Duin.h
index de5eb09..19e1b21 100644
--- a/Duin/src/Duin.h
+++ b/Duin/src/Duin.h
@@ -13,6 +13,7 @@
#include "Duin/Core/Debug/Log.h"
#include "Duin/Core/Debug/Profiler.h"
#include "Duin/Core/Debug/Timer.h"
+#include "Duin/Core/Debug/DebugDraw.h"
#include "Duin/Core/Maths/DuinMaths.h"
#include "Duin/Core/Structures/RenderStructs.h"
#include "Duin/Core/Structures/QuadTree.h"
diff --git a/Duin/src/Duin/Core/Debug/DebugDraw.cpp b/Duin/src/Duin/Core/Debug/DebugDraw.cpp
new file mode 100644
index 0000000..a833b3b
--- /dev/null
+++ b/Duin/src/Duin/Core/Debug/DebugDraw.cpp
@@ -0,0 +1,12 @@
+#include "dnpch.h"
+
+#include "DebugDraw.h"
+
+namespace Duin
+{
+ void DebugDraw::DrawLine(int x1, int y1, int x2, int y2, Color color)
+ {
+ ::Color rlColor = { color.r, color.g, color.b, color.a };
+ ::DrawLine(x1, y1, x2, y2, rlColor);
+ }
+}
\ No newline at end of file
diff --git a/Duin/src/Duin/Core/Debug/DebugDraw.h b/Duin/src/Duin/Core/Debug/DebugDraw.h
new file mode 100644
index 0000000..919cb06
--- /dev/null
+++ b/Duin/src/Duin/Core/Debug/DebugDraw.h
@@ -0,0 +1,15 @@
+#pragma once
+
+#include "Duin/Core/Core.h"
+#include "Duin/Core/Structures/RenderStructs.h"
+
+#include
+
+namespace Duin
+{
+ class DUIN_API DebugDraw
+ {
+ public:
+ static void DrawLine(int x1, int y1, int x2, int y2, Color color);
+ };
+}
\ No newline at end of file
diff --git a/Duin/src/Duin/Core/Structures/Delaunay.h b/Duin/src/Duin/Core/Structures/Delaunay.h
new file mode 100644
index 0000000..a719cfc
--- /dev/null
+++ b/Duin/src/Duin/Core/Structures/Delaunay.h
@@ -0,0 +1,16 @@
+#pragma once
+
+#include "Duin/Core/Core.h"
+
+#include
+
+namespace Duin
+{
+ class DUIN_API Delauney
+ {
+ public:
+
+ private:
+
+ };
+}
\ No newline at end of file
diff --git a/Duin/vendor/cdt/.clang-format b/Duin/vendor/cdt/.clang-format
new file mode 100644
index 0000000..6892bad
--- /dev/null
+++ b/Duin/vendor/cdt/.clang-format
@@ -0,0 +1,52 @@
+# ================================
+# Can be used when needed locally:
+# ================================
+ SortIncludes: true
+ SortUsingDeclarations: true
+
+AccessModifierOffset: -4
+AlignAfterOpenBracket: AlwaysBreak
+AllowAllParametersOfDeclarationOnNextLine: false
+AllowShortBlocksOnASingleLine: false
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: None
+AllowShortIfStatementsOnASingleLine: false
+AllowShortLoopsOnASingleLine: false
+AlwaysBreakTemplateDeclarations: true
+BinPackArguments: false
+BinPackParameters: false
+BreakConstructorInitializersBeforeComma: true
+ColumnLimit: 80
+ConstructorInitializerIndentWidth: 4
+ContinuationIndentWidth: 4
+DerivePointerAlignment: false
+PointerAlignment: Left
+IndentWidth: 4
+Language: Cpp
+NamespaceIndentation: None
+SpaceBeforeParens: Never
+SpacesBeforeTrailingComments: 1
+Standard: Cpp03
+UseTab: Never
+
+# =====================
+# Clang 5 new features:
+# =====================
+BreakBeforeBraces: Custom
+BraceWrapping:
+ AfterClass: true
+ AfterControlStatement: true
+ AfterEnum : true
+ AfterFunction : true
+ AfterNamespace : true
+ AfterStruct : true
+ AfterUnion : true
+ BeforeCatch : true
+ BeforeElse : true
+ IndentBraces : false
+ SplitEmptyFunction: false
+ SplitEmptyRecord: false
+ SplitEmptyNamespace: true
+BreakBeforeInheritanceComma: true
+FixNamespaceComments: true
+ReflowComments: true
\ No newline at end of file
diff --git a/Duin/vendor/cdt/.gitignore b/Duin/vendor/cdt/.gitignore
new file mode 100644
index 0000000..47561a8
--- /dev/null
+++ b/Duin/vendor/cdt/.gitignore
@@ -0,0 +1,86 @@
+# This file is used to ignore files which are generated
+# ----------------------------------------------------------------------------
+
+build/
+cmake-build*/
+*~
+*.autosave
+*.a
+*.core
+*.moc
+*.o
+*.obj
+*.orig
+*.rej
+*.so
+*.so.*
+*_pch.h.cpp
+*_resource.rc
+*.qm
+.#*
+*.*#
+core
+!core/
+tags
+.DS_Store
+.directory
+*.debug
+Makefile*
+*.prl
+*.app
+moc_*.cpp
+ui_*.h
+qrc_*.cpp
+Thumbs.db
+*.res
+*.rc
+/.qmake.cache
+/.qmake.stash
+
+# qtcreator generated files
+*.pro.user*
+
+# xemacs temporary files
+*.flc
+
+# Vim temporary files
+.*.swp
+
+# Visual Studio generated files
+*.ib_pdb_index
+*.idb
+*.ilk
+*.pdb
+*.sln
+*.suo
+*.vcproj
+*vcproj.*.*.user
+*.ncb
+*.sdf
+*.opensdf
+*.vcxproj
+*vcxproj.*
+
+# MinGW generated files
+*.Debug
+*.Release
+
+# Python byte code
+*.pyc
+
+# Binaries
+# --------
+*.dll
+*.exe
+
+# xcode
+*.xcode*
+# moc
+moc_*.h
+
+# CLion
+*.idea*
+
+# Visual code files
+*.code-workspace
+*.vscode
\ No newline at end of file
diff --git a/Duin/vendor/cdt/.gitmodules b/Duin/vendor/cdt/.gitmodules
new file mode 100644
index 0000000..bd1b778
--- /dev/null
+++ b/Duin/vendor/cdt/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "CDT/tests/Catch2"]
+ path = CDT/tests/Catch2
+ url = https://github.com/catchorg/Catch2.git
diff --git a/Duin/vendor/cdt/.mailmap b/Duin/vendor/cdt/.mailmap
new file mode 100644
index 0000000..5da42bf
--- /dev/null
+++ b/Duin/vendor/cdt/.mailmap
@@ -0,0 +1,4 @@
+artem-ogre
+artem-ogre
+artem-ogre
+kalleakerblom
diff --git a/Duin/vendor/cdt/CDT/CMakeLists.txt b/Duin/vendor/cdt/CDT/CMakeLists.txt
new file mode 100644
index 0000000..781b28f
--- /dev/null
+++ b/Duin/vendor/cdt/CDT/CMakeLists.txt
@@ -0,0 +1,273 @@
+cmake_minimum_required(VERSION 3.4)
+
+project(
+ "CDT"
+ VERSION 1.3.0
+ DESCRIPTION
+ "C++ library for constrained Delaunay triangulation"
+ HOMEPAGE_URL "https://github.com/artem-ogre/CDT"
+ LANGUAGES CXX)
+
+# -------
+# target
+# -------
+
+# export all symbols as we do it by instantiating templates anyway
+set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
+
+# options
+option(CDT_USE_AS_COMPILED_LIBRARY
+ "If enabled templates for float and double will be instantiated and compiled into a library")
+
+option(CDT_USE_64_BIT_INDEX_TYPE
+ "If enabled 64bits are used to store vertex/triangle index types. Otherwise 32bits are used (up to 4.2bn items)"
+ OFF)
+
+option(CDT_ENABLE_TESTING
+ "If enabled tests target will ge generated)"
+ OFF)
+
+option(CDT_USE_STRONG_TYPING
+ "If enabled uses strong typing for types: useful for development and debugging"
+ OFF)
+
+option(CDT_DEVELOPER_BUILD
+ "Enables all warnings."
+ OFF)
+
+if(CDT_DEVELOPER_BUILD)
+ if (MSVC)
+ # warning level 4 and all warnings as errors
+ add_compile_options(/W4 /WX)
+ else()
+ # lots of warnings and all warnings as errors
+ add_compile_options(-Wall -Wextra -pedantic -Wno-comment)
+ endif()
+endif()
+
+# check if Boost is needed
+if(cxx_std_11 IN_LIST CMAKE_CXX_COMPILE_FEATURES)
+ # Work-around as AppleClang 11 defaults to c++98 by default
+ if(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
+ message(STATUS "AppleClang work-around: set CMAKE_CXX_STANDARD to 11")
+ set(CMAKE_CXX_STANDARD 11)
+ endif()
+else()
+ message(STATUS "Compiler does not support C++11: falling back to Boost")
+ set(CDT_USE_BOOST ON)
+endif()
+
+if(CDT_USE_STRONG_TYPING)
+ set(CDT_USE_BOOST ON)
+endif()
+
+message(STATUS "CDT_USE_AS_COMPILED_LIBRARY is ${CDT_USE_AS_COMPILED_LIBRARY}")
+message(STATUS "CDT_USE_64_BIT_INDEX_TYPE is ${CDT_USE_64_BIT_INDEX_TYPE}")
+message(STATUS "CDT_ENABLE_TESTING is ${CDT_ENABLE_TESTING}")
+message(STATUS "CDT_USE_STRONG_TYPING is ${CDT_USE_STRONG_TYPING}")
+message(STATUS "CDT_DEVELOPER_BUILD is ${CDT_DEVELOPER_BUILD}")
+
+# Use boost for c++98 versions of c++11 containers or for Boost::rtree
+if(CDT_USE_BOOST)
+ find_package(Boost REQUIRED)
+endif()
+
+
+# configure target
+set(cdt_include_dirs
+ include
+ extras
+)
+
+if(CDT_USE_AS_COMPILED_LIBRARY)
+ set(cdt_scope PUBLIC)
+ set(cdt_sources
+ src/CDT.cpp
+ )
+ set(cdt_headers
+ include/CDT.h
+ include/CDTUtils.h
+ include/Triangulation.h
+ include/KDTree.h
+ include/LocatorKDTree.h
+ include/remove_at.hpp
+ include/CDT.hpp
+ include/CDTUtils.hpp
+ include/Triangulation.hpp
+ include/predicates.h
+ extras/VerifyTopology.h
+ extras/InitializeWithGrid.h
+ )
+ add_library(${PROJECT_NAME} ${cdt_sources} ${cdt_headers})
+ # Set symbols visibility to hidden by default
+ set_target_properties(
+ ${PROJECT_NAME}
+ PROPERTIES
+ VERSION ${PROJECT_VERSION}
+ SOVERSION ${PROJECT_VERSION}
+ CXX_VISIBILITY_PRESET hidden
+ VISIBILITY_INLINES_HIDDEN 1
+ )
+ # Generate export header and add it to include directories
+ include(GenerateExportHeader)
+ generate_export_header(${PROJECT_NAME})
+ target_include_directories(
+ ${PROJECT_NAME} ${cdt_scope}
+ $
+ )
+ target_sources(
+ ${PROJECT_NAME} ${cdt_scope}
+ $
+ )
+
+else()
+ set(cdt_scope INTERFACE)
+ add_library(${PROJECT_NAME} INTERFACE)
+endif()
+
+add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
+
+foreach(dir_ ${cdt_include_dirs})
+ target_include_directories(
+ ${PROJECT_NAME}
+ ${cdt_scope}
+ $
+ )
+endforeach()
+
+target_include_directories(
+ ${PROJECT_NAME} INTERFACE $)
+
+target_compile_definitions(
+ ${PROJECT_NAME}
+ ${cdt_scope}
+ $<$:CDT_USE_BOOST>
+ $<$:CDT_USE_AS_COMPILED_LIBRARY>
+ $<$:CDT_USE_64_BIT_INDEX_TYPE>
+ $<$:CDT_USE_STRONG_TYPING>
+)
+
+target_link_libraries(${PROJECT_NAME} ${cdt_scope} $<$:Boost::boost>)
+
+# -------------
+# installation
+# -------------
+
+
+include(GNUInstallDirs)
+
+# install and export the library
+foreach(dir_ ${cdt_include_dirs})
+ install(DIRECTORY ${dir_}/ DESTINATION include)
+endforeach()
+
+install(
+ TARGETS ${PROJECT_NAME}
+ EXPORT ${PROJECT_NAME}Config
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+)
+
+install(
+ FILES
+ $<$:${CMAKE_CURRENT_BINARY_DIR}/cdt_export.h>
+ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
+)
+
+install(EXPORT ${PROJECT_NAME}Config NAMESPACE CDT:: DESTINATION cmake)
+
+# ------------
+# documentation
+# ------------
+
+# work-around to detect custom-doxygen
+#set(DOXYGEN_EXECUTABLE /usr/local/bin/doxygen)
+
+find_package(Doxygen 1.9)
+if(DOXYGEN_FOUND)
+ message(STATUS "Doxygen found: adding documentation target.")
+ set(DOXYGEN_EXCLUDE_PATTERNS
+ */cmake-build*
+ */predicates.h
+ conanfile.py
+ ${PROJECT_SOURCE_DIR}/tests/*
+ )
+ # doxygen settings can be set here, prefixed with "DOXYGEN_"
+ set(DOXYGEN_SOURCE_BROWSER YES)
+ set(DOXYGEN_JAVADOC_AUTOBRIEF YES)
+ set(DOXYGEN_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/docs")
+ set(CDT_DOCS_DIRECTORY ${PROJECT_SOURCE_DIR}/../docs)
+ set(DOXYGEN_USE_MDFILE_AS_MAINPAGE ${CDT_DOCS_DIRECTORY}/README.md)
+ set(DOXYGEN_IMAGE_PATH ${CDT_DOCS_DIRECTORY}/images)
+
+ set(DOXYGEN_GENERATE_TREEVIEW YES)
+ set(CDT_DOXYGEN_AWESOME_DIRECTORY ${CDT_DOCS_DIRECTORY}/doxygen-custom/doxygen-awesome)
+ set(DOXYGEN_HTML_EXTRA_STYLESHEET
+ ${CDT_DOXYGEN_AWESOME_DIRECTORY}/doxygen-awesome.css
+ ${CDT_DOXYGEN_AWESOME_DIRECTORY}/doxygen-awesome-sidebar-only.css
+ ${CDT_DOXYGEN_AWESOME_DIRECTORY}/doxygen-awesome-sidebar-only-darkmode-toggle.css
+ ${CDT_DOCS_DIRECTORY}/doxygen-custom/custom.css
+ )
+ set(DOXYGEN_HTML_HEADER ${PROJECT_SOURCE_DIR}/../docs/doxygen-custom/header.html)
+ set(DOXYGEN_HTML_EXTRA_FILES
+ ${CDT_DOCS_DIRECTORY}/doxygen-custom/logo.svg
+ ${CDT_DOCS_DIRECTORY}/doxygen-custom/favicon/favicon.ico
+ ${CDT_DOCS_DIRECTORY}/doxygen-custom/favicon/apple-touch-icon.png
+ ${CDT_DOCS_DIRECTORY}/doxygen-custom/favicon/android-chrome-192x192.png
+ ${CDT_DOCS_DIRECTORY}/doxygen-custom/favicon/android-chrome-512x512.png
+ ${CDT_DOCS_DIRECTORY}/doxygen-custom/favicon/site.webmanifest
+ ${CDT_DOXYGEN_AWESOME_DIRECTORY}/doxygen-awesome-darkmode-toggle.js
+ ${CDT_DOXYGEN_AWESOME_DIRECTORY}/doxygen-awesome-fragment-copy-button.js
+ ${CDT_DOXYGEN_AWESOME_DIRECTORY}/doxygen-awesome-paragraph-link.js
+ ${CDT_DOXYGEN_AWESOME_DIRECTORY}/toggle-alternative-theme.js
+ )
+ set(DOXYGEN_LAYOUT_FILE ${CDT_DOCS_DIRECTORY}/doxygen-custom/DoxygenLayout.xml)
+ # this target will only be built if specifically asked to.
+ # run "make api-docs" to create the doxygen documentation
+ doxygen_add_docs(
+ ${PROJECT_NAME}-docs
+ ${PROJECT_SOURCE_DIR}
+ ${CDT_DOCS_DIRECTORY}
+ COMMENT "Generate doxygen documentation for CDT."
+ )
+ # copy README.md images to doxygen so that they are displayed
+ add_custom_command(
+ TARGET ${PROJECT_NAME}-docs POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy_directory
+ ${PROJECT_SOURCE_DIR}/../docs/images
+ ${DOXYGEN_OUTPUT_DIRECTORY}/html/images
+ )
+endif(DOXYGEN_FOUND)
+
+
+# ------------
+# tests
+# ------------
+
+if(CDT_ENABLE_TESTING)
+ include(CTest)
+ enable_testing()
+ # add Catch2
+ find_package(Catch2 3 QUIET)
+ if(Catch2_FOUND)
+ list(APPEND CMAKE_MODULE_PATH ${catch2_SOURCE_DIR}/extras)
+ else()
+ set(Catch2_directory ${PROJECT_SOURCE_DIR}/tests/Catch2)
+ add_subdirectory(${Catch2_directory})
+ list(APPEND CMAKE_MODULE_PATH ${Catch2_directory}/extras)
+ endif()
+ set(TEST_TARGET_NAME ${PROJECT_NAME}-tests)
+ add_executable(${TEST_TARGET_NAME})
+ set_property(TARGET ${TEST_TARGET_NAME} PROPERTY CXX_STANDARD 17)
+ target_sources(${TEST_TARGET_NAME} PRIVATE tests/cdt.test.cpp)
+ target_link_libraries(
+ ${TEST_TARGET_NAME}
+ PRIVATE
+ Catch2::Catch2WithMain
+ CDT::CDT
+ )
+ include(Catch)
+ catch_discover_tests(${TEST_TARGET_NAME} WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/tests")
+endif()
diff --git a/Duin/vendor/cdt/CDT/LICENSE b/Duin/vendor/cdt/CDT/LICENSE
new file mode 100644
index 0000000..14e2f77
--- /dev/null
+++ b/Duin/vendor/cdt/CDT/LICENSE
@@ -0,0 +1,373 @@
+Mozilla Public License Version 2.0
+==================================
+
+1. Definitions
+--------------
+
+1.1. "Contributor"
+ means each individual or legal entity that creates, contributes to
+ the creation of, or owns Covered Software.
+
+1.2. "Contributor Version"
+ means the combination of the Contributions of others (if any) used
+ by a Contributor and that particular Contributor's Contribution.
+
+1.3. "Contribution"
+ means Covered Software of a particular Contributor.
+
+1.4. "Covered Software"
+ means Source Code Form to which the initial Contributor has attached
+ the notice in Exhibit A, the Executable Form of such Source Code
+ Form, and Modifications of such Source Code Form, in each case
+ including portions thereof.
+
+1.5. "Incompatible With Secondary Licenses"
+ means
+
+ (a) that the initial Contributor has attached the notice described
+ in Exhibit B to the Covered Software; or
+
+ (b) that the Covered Software was made available under the terms of
+ version 1.1 or earlier of the License, but not also under the
+ terms of a Secondary License.
+
+1.6. "Executable Form"
+ means any form of the work other than Source Code Form.
+
+1.7. "Larger Work"
+ means a work that combines Covered Software with other material, in
+ a separate file or files, that is not Covered Software.
+
+1.8. "License"
+ means this document.
+
+1.9. "Licensable"
+ means having the right to grant, to the maximum extent possible,
+ whether at the time of the initial grant or subsequently, any and
+ all of the rights conveyed by this License.
+
+1.10. "Modifications"
+ means any of the following:
+
+ (a) any file in Source Code Form that results from an addition to,
+ deletion from, or modification of the contents of Covered
+ Software; or
+
+ (b) any new file in Source Code Form that contains any Covered
+ Software.
+
+1.11. "Patent Claims" of a Contributor
+ means any patent claim(s), including without limitation, method,
+ process, and apparatus claims, in any patent Licensable by such
+ Contributor that would be infringed, but for the grant of the
+ License, by the making, using, selling, offering for sale, having
+ made, import, or transfer of either its Contributions or its
+ Contributor Version.
+
+1.12. "Secondary License"
+ means either the GNU General Public License, Version 2.0, the GNU
+ Lesser General Public License, Version 2.1, the GNU Affero General
+ Public License, Version 3.0, or any later versions of those
+ licenses.
+
+1.13. "Source Code Form"
+ means the form of the work preferred for making modifications.
+
+1.14. "You" (or "Your")
+ means an individual or a legal entity exercising rights under this
+ License. For legal entities, "You" includes any entity that
+ controls, is controlled by, or is under common control with You. For
+ purposes of this definition, "control" means (a) the power, direct
+ or indirect, to cause the direction or management of such entity,
+ whether by contract or otherwise, or (b) ownership of more than
+ fifty percent (50%) of the outstanding shares or beneficial
+ ownership of such entity.
+
+2. License Grants and Conditions
+--------------------------------
+
+2.1. Grants
+
+Each Contributor hereby grants You a world-wide, royalty-free,
+non-exclusive license:
+
+(a) under intellectual property rights (other than patent or trademark)
+ Licensable by such Contributor to use, reproduce, make available,
+ modify, display, perform, distribute, and otherwise exploit its
+ Contributions, either on an unmodified basis, with Modifications, or
+ as part of a Larger Work; and
+
+(b) under Patent Claims of such Contributor to make, use, sell, offer
+ for sale, have made, import, and otherwise transfer either its
+ Contributions or its Contributor Version.
+
+2.2. Effective Date
+
+The licenses granted in Section 2.1 with respect to any Contribution
+become effective for each Contribution on the date the Contributor first
+distributes such Contribution.
+
+2.3. Limitations on Grant Scope
+
+The licenses granted in this Section 2 are the only rights granted under
+this License. No additional rights or licenses will be implied from the
+distribution or licensing of Covered Software under this License.
+Notwithstanding Section 2.1(b) above, no patent license is granted by a
+Contributor:
+
+(a) for any code that a Contributor has removed from Covered Software;
+ or
+
+(b) for infringements caused by: (i) Your and any other third party's
+ modifications of Covered Software, or (ii) the combination of its
+ Contributions with other software (except as part of its Contributor
+ Version); or
+
+(c) under Patent Claims infringed by Covered Software in the absence of
+ its Contributions.
+
+This License does not grant any rights in the trademarks, service marks,
+or logos of any Contributor (except as may be necessary to comply with
+the notice requirements in Section 3.4).
+
+2.4. Subsequent Licenses
+
+No Contributor makes additional grants as a result of Your choice to
+distribute the Covered Software under a subsequent version of this
+License (see Section 10.2) or under the terms of a Secondary License (if
+permitted under the terms of Section 3.3).
+
+2.5. Representation
+
+Each Contributor represents that the Contributor believes its
+Contributions are its original creation(s) or it has sufficient rights
+to grant the rights to its Contributions conveyed by this License.
+
+2.6. Fair Use
+
+This License is not intended to limit any rights You have under
+applicable copyright doctrines of fair use, fair dealing, or other
+equivalents.
+
+2.7. Conditions
+
+Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
+in Section 2.1.
+
+3. Responsibilities
+-------------------
+
+3.1. Distribution of Source Form
+
+All distribution of Covered Software in Source Code Form, including any
+Modifications that You create or to which You contribute, must be under
+the terms of this License. You must inform recipients that the Source
+Code Form of the Covered Software is governed by the terms of this
+License, and how they can obtain a copy of this License. You may not
+attempt to alter or restrict the recipients' rights in the Source Code
+Form.
+
+3.2. Distribution of Executable Form
+
+If You distribute Covered Software in Executable Form then:
+
+(a) such Covered Software must also be made available in Source Code
+ Form, as described in Section 3.1, and You must inform recipients of
+ the Executable Form how they can obtain a copy of such Source Code
+ Form by reasonable means in a timely manner, at a charge no more
+ than the cost of distribution to the recipient; and
+
+(b) You may distribute such Executable Form under the terms of this
+ License, or sublicense it under different terms, provided that the
+ license for the Executable Form does not attempt to limit or alter
+ the recipients' rights in the Source Code Form under this License.
+
+3.3. Distribution of a Larger Work
+
+You may create and distribute a Larger Work under terms of Your choice,
+provided that You also comply with the requirements of this License for
+the Covered Software. If the Larger Work is a combination of Covered
+Software with a work governed by one or more Secondary Licenses, and the
+Covered Software is not Incompatible With Secondary Licenses, this
+License permits You to additionally distribute such Covered Software
+under the terms of such Secondary License(s), so that the recipient of
+the Larger Work may, at their option, further distribute the Covered
+Software under the terms of either this License or such Secondary
+License(s).
+
+3.4. Notices
+
+You may not remove or alter the substance of any license notices
+(including copyright notices, patent notices, disclaimers of warranty,
+or limitations of liability) contained within the Source Code Form of
+the Covered Software, except that You may alter any license notices to
+the extent required to remedy known factual inaccuracies.
+
+3.5. Application of Additional Terms
+
+You may choose to offer, and to charge a fee for, warranty, support,
+indemnity or liability obligations to one or more recipients of Covered
+Software. However, You may do so only on Your own behalf, and not on
+behalf of any Contributor. You must make it absolutely clear that any
+such warranty, support, indemnity, or liability obligation is offered by
+You alone, and You hereby agree to indemnify every Contributor for any
+liability incurred by such Contributor as a result of warranty, support,
+indemnity or liability terms You offer. You may include additional
+disclaimers of warranty and limitations of liability specific to any
+jurisdiction.
+
+4. Inability to Comply Due to Statute or Regulation
+---------------------------------------------------
+
+If it is impossible for You to comply with any of the terms of this
+License with respect to some or all of the Covered Software due to
+statute, judicial order, or regulation then You must: (a) comply with
+the terms of this License to the maximum extent possible; and (b)
+describe the limitations and the code they affect. Such description must
+be placed in a text file included with all distributions of the Covered
+Software under this License. Except to the extent prohibited by statute
+or regulation, such description must be sufficiently detailed for a
+recipient of ordinary skill to be able to understand it.
+
+5. Termination
+--------------
+
+5.1. The rights granted under this License will terminate automatically
+if You fail to comply with any of its terms. However, if You become
+compliant, then the rights granted under this License from a particular
+Contributor are reinstated (a) provisionally, unless and until such
+Contributor explicitly and finally terminates Your grants, and (b) on an
+ongoing basis, if such Contributor fails to notify You of the
+non-compliance by some reasonable means prior to 60 days after You have
+come back into compliance. Moreover, Your grants from a particular
+Contributor are reinstated on an ongoing basis if such Contributor
+notifies You of the non-compliance by some reasonable means, this is the
+first time You have received notice of non-compliance with this License
+from such Contributor, and You become compliant prior to 30 days after
+Your receipt of the notice.
+
+5.2. If You initiate litigation against any entity by asserting a patent
+infringement claim (excluding declaratory judgment actions,
+counter-claims, and cross-claims) alleging that a Contributor Version
+directly or indirectly infringes any patent, then the rights granted to
+You by any and all Contributors for the Covered Software under Section
+2.1 of this License shall terminate.
+
+5.3. In the event of termination under Sections 5.1 or 5.2 above, all
+end user license agreements (excluding distributors and resellers) which
+have been validly granted by You or Your distributors under this License
+prior to termination shall survive termination.
+
+************************************************************************
+* *
+* 6. Disclaimer of Warranty *
+* ------------------------- *
+* *
+* Covered Software is provided under this License on an "as is" *
+* basis, without warranty of any kind, either expressed, implied, or *
+* statutory, including, without limitation, warranties that the *
+* Covered Software is free of defects, merchantable, fit for a *
+* particular purpose or non-infringing. The entire risk as to the *
+* quality and performance of the Covered Software is with You. *
+* Should any Covered Software prove defective in any respect, You *
+* (not any Contributor) assume the cost of any necessary servicing, *
+* repair, or correction. This disclaimer of warranty constitutes an *
+* essential part of this License. No use of any Covered Software is *
+* authorized under this License except under this disclaimer. *
+* *
+************************************************************************
+
+************************************************************************
+* *
+* 7. Limitation of Liability *
+* -------------------------- *
+* *
+* Under no circumstances and under no legal theory, whether tort *
+* (including negligence), contract, or otherwise, shall any *
+* Contributor, or anyone who distributes Covered Software as *
+* permitted above, be liable to You for any direct, indirect, *
+* special, incidental, or consequential damages of any character *
+* including, without limitation, damages for lost profits, loss of *
+* goodwill, work stoppage, computer failure or malfunction, or any *
+* and all other commercial damages or losses, even if such party *
+* shall have been informed of the possibility of such damages. This *
+* limitation of liability shall not apply to liability for death or *
+* personal injury resulting from such party's negligence to the *
+* extent applicable law prohibits such limitation. Some *
+* jurisdictions do not allow the exclusion or limitation of *
+* incidental or consequential damages, so this exclusion and *
+* limitation may not apply to You. *
+* *
+************************************************************************
+
+8. Litigation
+-------------
+
+Any litigation relating to this License may be brought only in the
+courts of a jurisdiction where the defendant maintains its principal
+place of business and such litigation shall be governed by laws of that
+jurisdiction, without reference to its conflict-of-law provisions.
+Nothing in this Section shall prevent a party's ability to bring
+cross-claims or counter-claims.
+
+9. Miscellaneous
+----------------
+
+This License represents the complete agreement concerning the subject
+matter hereof. If any provision of this License is held to be
+unenforceable, such provision shall be reformed only to the extent
+necessary to make it enforceable. Any law or regulation which provides
+that the language of a contract shall be construed against the drafter
+shall not be used to construe this License against a Contributor.
+
+10. Versions of the License
+---------------------------
+
+10.1. New Versions
+
+Mozilla Foundation is the license steward. Except as provided in Section
+10.3, no one other than the license steward has the right to modify or
+publish new versions of this License. Each version will be given a
+distinguishing version number.
+
+10.2. Effect of New Versions
+
+You may distribute the Covered Software under the terms of the version
+of the License under which You originally received the Covered Software,
+or under the terms of any subsequent version published by the license
+steward.
+
+10.3. Modified Versions
+
+If you create software not governed by this License, and you want to
+create a new license for such software, you may create and use a
+modified version of this License if you rename the license and remove
+any references to the name of the license steward (except to note that
+such modified license differs from this License).
+
+10.4. Distributing Source Code Form that is Incompatible With Secondary
+Licenses
+
+If You choose to distribute Source Code Form that is Incompatible With
+Secondary Licenses under the terms of this version of the License, the
+notice described in Exhibit B of this License must be attached.
+
+Exhibit A - Source Code Form License Notice
+-------------------------------------------
+
+ This Source Code Form is subject to the terms of the Mozilla Public
+ License, v. 2.0. If a copy of the MPL was not distributed with this
+ file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+If it is not possible or desirable to put the notice in a particular
+file, then You may include the notice in a location (such as a LICENSE
+file in a relevant directory) where a recipient would be likely to look
+for such a notice.
+
+You may add additional accurate notices of copyright ownership.
+
+Exhibit B - "Incompatible With Secondary Licenses" Notice
+---------------------------------------------------------
+
+ This Source Code Form is "Incompatible With Secondary Licenses", as
+ defined by the Mozilla Public License, v. 2.0.
diff --git a/Duin/vendor/cdt/CDT/conan_basic_setup.cmake b/Duin/vendor/cdt/CDT/conan_basic_setup.cmake
new file mode 100644
index 0000000..4949c3c
--- /dev/null
+++ b/Duin/vendor/cdt/CDT/conan_basic_setup.cmake
@@ -0,0 +1,10 @@
+if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/conanbuildinfo.cmake")
+ message(STATUS "Detected Conan build: perform conan setup")
+ include("${CMAKE_CURRENT_SOURCE_DIR}/conanbuildinfo.cmake")
+ # See: https://docs.conan.io/en/latest/howtos/manage_shared_libraries/rpaths.html#default-conan-approach
+ if(APPLE)
+ conan_basic_setup(KEEP_RPATHS)
+ else()
+ conan_basic_setup()
+ endif()
+endif()
\ No newline at end of file
diff --git a/Duin/vendor/cdt/CDT/conanfile.py b/Duin/vendor/cdt/CDT/conanfile.py
new file mode 100644
index 0000000..9c60a13
--- /dev/null
+++ b/Duin/vendor/cdt/CDT/conanfile.py
@@ -0,0 +1,59 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+from conan import ConanFile
+from conan.tools.cmake import CMake, CMakeToolchain
+from conan.tools.files import collect_libs
+
+class CDTConan(ConanFile):
+ name = "cdt"
+ version = "1.3.0"
+ license = "MPL-2.0 License"
+ url = "https://github.com/artem-ogre/CDT"
+ description = "Numerically robust C++ implementation of constrained Delaunay triangulation (CDT)"
+ settings = "os", "compiler", "build_type", "arch"
+ generators = "CMakeDeps"
+ options = {
+ "shared": [True, False],
+ "use_boost": [True, False],
+ "as_compiled_library": [True, False],
+ "enable_testing": [True, False],
+ }
+ default_options = {
+ "shared": False,
+ "use_boost": False,
+ "as_compiled_library": False,
+ }
+ exports_sources = "*", "!.idea", "!conanfile.py"
+
+ def requirements(self):
+ if self.options.use_boost:
+ self.requires("boost/1.83.0")
+ self.requires("catch2/3.4.0")
+
+ def configure(self):
+ if self.options.use_boost:
+ self.options["boost"].header_only = True
+
+ def generate(self):
+ tc = CMakeToolchain(self)
+ tc.variables["CDT_USE_BOOST"] = self.options.use_boost
+ tc.cache_variables["CDT_USE_AS_COMPILED_LIBRARY"] = self.options.as_compiled_library
+ tc.cache_variables["CMAKE_PROJECT_CDT_INCLUDE"] = "conan_basic_setup.cmake"
+ tc.cache_variables["CDT_ENABLE_TESTING"] = self.options.enable_testing
+ tc.generate()
+
+ def build(self):
+ cmake = CMake(self)
+ cmake.configure()
+ cmake.build()
+ if self.options.enable_testing:
+ cmake.test(cli_args=["--verbose"])
+
+ def package(self):
+ cmake = CMake(self)
+ cmake.install()
+
+ def package_info(self):
+ self.cpp_info.libs = collect_libs(self)
diff --git a/Duin/vendor/cdt/CDT/extras/InitializeWithGrid.h b/Duin/vendor/cdt/CDT/extras/InitializeWithGrid.h
new file mode 100644
index 0000000..0bf3b04
--- /dev/null
+++ b/Duin/vendor/cdt/CDT/extras/InitializeWithGrid.h
@@ -0,0 +1,242 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+/**
+ * @file
+ * Helper function to initialize triangulation with regular grid instead of
+ * super-triangle
+ */
+
+#ifndef CDT_HmXGv083vZCrT3OXASD9
+#define CDT_HmXGv083vZCrT3OXASD9
+
+#include
+#include
+
+#ifdef CDT_CXX11_IS_SUPPORTED
+#include
+#endif
+#include
+#include
+#include
+
+namespace CDT
+{
+namespace detail
+{
+
+/**
+ * Generate grid vertices given of X- and Y-ticks
+ *
+ * @tparam OutputVertIt output vertices iterator
+ * @tparam OutputTriIt output triangles iterator
+ * @tparam TXCoordIter iterator dereferencing to X coordinate
+ * @tparam TYCoordIter iterator dereferencing to Y coordinate
+ * @param outFirst the beginning of the destination range
+ * @param xfirst beginning of X-ticks range
+ * @param xlast end of X-ticks range
+ * @param yfirst beginning of Y-ticks range
+ * @param ylast end of Y-ticks range
+ */
+template <
+ typename OutputVertIt,
+ typename OutputTriIt,
+ typename TXCoordIter,
+ typename TYCoordIter>
+void generateGridVertices(
+ OutputVertIt outVertsFirst,
+ OutputTriIt outTrisFirst,
+ const TXCoordIter xfirst,
+ const TXCoordIter xlast,
+ const TYCoordIter yfirst,
+ const TYCoordIter ylast)
+{
+ typedef typename std::iterator_traits::value_type T;
+ const std::size_t xres = std::distance(xfirst, xlast) - 1;
+ const std::size_t yres = std::distance(yfirst, ylast) - 1;
+
+ TXCoordIter yiter = yfirst;
+ for(std::size_t iy = 0; yiter != ylast; ++yiter, ++iy)
+ {
+ TXCoordIter xiter = xfirst;
+ for(std::size_t ix = 0; xiter != xlast; ++xiter, ++ix)
+ {
+ *outVertsFirst++ = V2d::make(*xiter, *yiter);
+ const std::size_t i = iy * xres + ix;
+ TriIndVec vTris;
+ vTris.reserve(6);
+ // left-up
+ if(ix > 0 && iy < yres)
+ {
+ vTris.push_back(static_cast(2 * (i - 1)));
+ vTris.push_back(static_cast(2 * (i - 1) + 1));
+ }
+ // right-up
+ if(ix < xres && iy < yres)
+ {
+ vTris.push_back(static_cast(2 * i));
+ }
+ // left-down
+ if(ix > 0 && iy > 0)
+ {
+ vTris.push_back(static_cast(2 * (i - xres - 1) + 1));
+ }
+ // right-down
+ if(ix < xres && iy > 0)
+ {
+ vTris.push_back(static_cast(2 * (i - xres)));
+ vTris.push_back(static_cast(2 * (i - xres) + 1));
+ }
+#ifdef CDT_CXX11_IS_SUPPORTED
+ *outTrisFirst++ = std::move(vTris.front());
+#else
+ *outTrisFirst++ = vTris;
+#endif
+ }
+ }
+}
+
+/**
+ * Generate grid triangles
+ *
+ * @tparam OutputIt output iterator
+ * @param outFirst the beginning of the destination range
+ * @param xres grid X-resolution
+ * @param yres grid Y-resolution
+ */
+template
+void generateGridTriangles(
+ OutputIt outFirst,
+ const IndexSizeType xres,
+ const IndexSizeType yres)
+{
+ for(IndexSizeType iy = 0; iy < yres; ++iy)
+ {
+ for(IndexSizeType ix = 0; ix < xres; ++ix)
+ {
+ // 2___3 v3
+ // |\ | /\
+ // | \ | n3/ \n2
+ // |__\| /____\
+ // 0 1 v1 n1 v2
+ const IndexSizeType i = iy * xres + ix;
+ const IndexSizeType iv = iy * (xres + 1) + ix;
+ const VertInd vv[4] = {
+ VertInd(iv),
+ VertInd(iv + 1),
+ VertInd(iv + xres + 1),
+ VertInd(iv + xres + 2)};
+ {
+ const Triangle t = {
+ {vv[0], vv[1], vv[2]},
+ {TriInd(iy ? 2 * i - xres * 2 + 1 : noNeighbor),
+ TriInd(2 * i + 1),
+ TriInd(ix ? 2 * i - 1 : noNeighbor)}};
+ *outFirst++ = t;
+ }
+ {
+ const Triangle t = {
+ {vv[1], vv[3], vv[2]},
+ {TriInd(ix < xres - 1 ? 2 * i + 2 : noNeighbor),
+ TriInd(iy < yres - 1 ? 2 * i + xres * 2 : noNeighbor),
+ TriInd(2 * i)}};
+ *outFirst++ = t;
+ }
+ }
+ }
+}
+
+} // namespace detail
+
+/**
+ * Make a triangulation that uses regular grid triangles instead of
+ * super-triangle
+ *
+ * @tparam T type of vertex coordinates (e.g., float, double)
+ * @tparam TNearPointLocator class providing locating near point for efficiently
+ * inserting new points.
+ * @param xmin minimum X-coordinate of grid
+ * @param xmax maximum X-coordinate of grid
+ * @param ymin minimum Y-coordinate of grid
+ * @param ymax maximum Y-coordinate of grid
+ * @param xres grid X-resolution
+ * @param yres grid Y-resolution
+ * @param out triangulation to initialize with grid super-geometry
+ */
+template
+void initializeWithRegularGrid(
+ const T xmin,
+ const T xmax,
+ const T ymin,
+ const T ymax,
+ const std::size_t xres,
+ const std::size_t yres,
+ Triangulation& out)
+{
+ std::vector xcoords;
+ std::vector ycoords;
+ xcoords.reserve(xres + 1);
+ ycoords.reserve(yres + 1);
+ const T xstep = (xmax - xmin) / xres;
+ T x = xmin;
+ for(std::size_t ix = 0; ix <= xres; ++ix, x += xstep)
+ xcoords.push_back(x);
+ const T ystep = (ymax - ymin) / yres;
+ T y = ymin;
+ for(std::size_t iy = 0; iy <= yres; ++iy, y += ystep)
+ ycoords.push_back(y);
+
+ return initializeWithIrregularGrid(
+ xcoords.begin(), xcoords.end(), ycoords.begin(), ycoords.end(), out);
+}
+
+/**
+ * Make a triangulation that uses irregular grid triangles instead of
+ * super-triangle. Irregular grid is given by collections of X- and Y-ticks
+ *
+ * @tparam T type of vertex coordinates (e.g., float, double)
+ * @tparam TNearPointLocator class providing locating near point for efficiently
+ * inserting new points.
+ * @tparam TXCoordIter iterator dereferencing to X coordinate
+ * @tparam TYCoordIter iterator dereferencing to Y coordinate
+ * @param xfirst beginning of X-ticks range
+ * @param xlast end of X-ticks range
+ * @param yfirst beginning of Y-ticks range
+ * @param ylast end of Y-ticks range
+ * @param out triangulation to initialize with grid super-geometry
+ */
+template <
+ typename T,
+ typename TNearPointLocator,
+ typename TXCoordIter,
+ typename TYCoordIter>
+void initializeWithIrregularGrid(
+ const TXCoordIter xfirst,
+ const TXCoordIter xlast,
+ const TYCoordIter yfirst,
+ const TYCoordIter ylast,
+ Triangulation& out)
+{
+ const std::size_t xres = std::distance(xfirst, xlast) - 1;
+ const std::size_t yres = std::distance(yfirst, ylast) - 1;
+ out.triangles.reserve(xres * yres * 2);
+ out.vertices.reserve((xres + 1) * (yres + 1));
+ out.VertTrisInternal().reserve((xres + 1) * (yres + 1));
+ detail::generateGridVertices(
+ std::back_inserter(out.vertices),
+ std::back_inserter(out.VertTrisInternal()),
+ xfirst,
+ xlast,
+ yfirst,
+ ylast);
+ detail::generateGridTriangles(
+ std::back_inserter(out.triangles),
+ static_cast(xres),
+ static_cast(yres));
+ out.initializedWithCustomSuperGeometry();
+}
+
+} // namespace CDT
+
+#endif
diff --git a/Duin/vendor/cdt/CDT/extras/VerifyTopology.h b/Duin/vendor/cdt/CDT/extras/VerifyTopology.h
new file mode 100644
index 0000000..3bcac63
--- /dev/null
+++ b/Duin/vendor/cdt/CDT/extras/VerifyTopology.h
@@ -0,0 +1,90 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+/**
+ * @file
+ * Helper function to verify if triangulation has no inconsistencies
+ */
+
+#ifndef CDT_Zahj4kpHLwFgkKtcOI1i
+#define CDT_Zahj4kpHLwFgkKtcOI1i
+
+#include
+
+#include
+
+namespace CDT
+{
+
+/**
+ * Verify that triangulation topology is consistent.
+ *
+ * Checks:
+ * - for each vertex adjacent triangles contain the vertex
+ * - each triangle's neighbor in turn has triangle as its neighbor
+ * - each of triangle's vertices has triangle as adjacent
+ *
+ * @tparam T type of vertex coordinates (e.g., float, double)
+ * @tparam TNearPointLocator class providing locating near point for efficiently
+ */
+template
+inline bool verifyTopology(const CDT::Triangulation& cdt)
+{
+ // Check if vertices' adjacent triangles contain vertex
+ const VerticesTriangles vertTris = calculateTrianglesByVertex(
+ cdt.triangles, static_cast(cdt.vertices.size()));
+ for(VertInd iV(0); iV < VertInd(cdt.vertices.size()); ++iV)
+ {
+ const TriIndVec& vTris = vertTris[iV];
+ typedef TriIndVec::const_iterator TriIndCit;
+ for(TriIndCit it = vTris.begin(); it != vTris.end(); ++it)
+ {
+ const array& vv = cdt.triangles[*it].vertices;
+ if(std::find(vv.begin(), vv.end(), iV) == vv.end())
+ return false;
+ }
+ }
+ // Check if triangle neighbor links are fine
+ for(TriInd iT(0); iT < TriInd(cdt.triangles.size()); ++iT)
+ {
+ const Triangle& t = cdt.triangles[iT];
+ typedef NeighborsArr3::const_iterator NCit;
+ for(NCit it = t.neighbors.begin(); it != t.neighbors.end(); ++it)
+ {
+ if(*it == noNeighbor)
+ continue;
+ const array& nn = cdt.triangles[*it].neighbors;
+ if(std::find(nn.begin(), nn.end(), iT) == nn.end())
+ return false;
+ }
+ }
+ // Check if triangle's vertices have triangle as adjacent
+ for(TriInd iT(0); iT < TriInd(cdt.triangles.size()); ++iT)
+ {
+ const Triangle& t = cdt.triangles[iT];
+ typedef VerticesArr3::const_iterator VCit;
+ for(VCit it = t.vertices.begin(); it != t.vertices.end(); ++it)
+ {
+ const TriIndVec& tt = vertTris[*it];
+ if(std::find(tt.begin(), tt.end(), iT) == tt.end())
+ return false;
+ }
+ }
+ return true;
+}
+
+/// Check that each vertex has a neighbor triangle
+template
+inline bool eachVertexHasNeighborTriangle(
+ const CDT::Triangulation& cdt)
+{
+ for(const auto& vt : cdt.VertTrisInternal())
+ if(vt == noNeighbor)
+ return false;
+ return true;
+}
+
+} // namespace CDT
+
+#endif
diff --git a/Duin/vendor/cdt/CDT/include/CDT.h b/Duin/vendor/cdt/CDT/include/CDT.h
new file mode 100644
index 0000000..a8055a3
--- /dev/null
+++ b/Duin/vendor/cdt/CDT/include/CDT.h
@@ -0,0 +1,448 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+/**
+ * @file
+ * Public API
+ */
+
+#ifndef CDT_lNrmUayWQaIR5fxnsg9B
+#define CDT_lNrmUayWQaIR5fxnsg9B
+
+#include "CDTUtils.h"
+#include "Triangulation.h"
+
+#include "remove_at.hpp"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+/// Namespace containing triangulation functionality
+namespace CDT
+{
+
+/** @defgroup API Public API
+ * Contains API for constrained and conforming Delaunay triangulations
+ */
+/// @{
+
+/**
+ * Type used for storing layer depths for triangles
+ * @note LayerDepth should support 60K+ layers, which could be to much or
+ * too little for some use cases. Feel free to re-define this typedef.
+ */
+typedef unsigned short LayerDepth;
+typedef LayerDepth BoundaryOverlapCount;
+
+/// Triangles by vertex index
+typedef std::vector VerticesTriangles;
+
+/** @defgroup helpers Helpers
+ * Helpers for working with CDT::Triangulation.
+ */
+/// @{
+
+/**
+ * Calculate triangles adjacent to vertices (triangles by vertex index)
+ * @param triangles triangulation
+ * @param verticesSize total number of vertices to pre-allocate the output
+ * @return triangles by vertex index
+ */
+CDT_EXPORT VerticesTriangles
+calculateTrianglesByVertex(const TriangleVec& triangles, VertInd verticesSize);
+
+/**
+ * Information about removed duplicated vertices.
+ *
+ * Contains mapping information and removed duplicates indices.
+ * @note vertices {0,1,2,3,4} where 0 and 3 are the same will produce mapping
+ * {0,1,2,0,3} (to new vertices {0,1,2,3}) and duplicates {3}
+ */
+struct CDT_EXPORT DuplicatesInfo
+{
+ std::vector mapping; ///< vertex index mapping
+ std::vector duplicates; ///< duplicates' indices
+};
+
+/**
+ * Find duplicates in given custom point-type range
+ * @note duplicates are points with exactly same X and Y coordinates
+ * @tparam TVertexIter iterator that dereferences to custom point type
+ * @tparam TGetVertexCoordX function object getting x coordinate from vertex.
+ * Getter signature: const TVertexIter::value_type& -> T
+ * @tparam TGetVertexCoordY function object getting y coordinate from vertex.
+ * Getter signature: const TVertexIter::value_type& -> T
+ * @param first beginning of the range of vertices
+ * @param last end of the range of vertices
+ * @param getX getter of X-coordinate
+ * @param getY getter of Y-coordinate
+ * @returns information about vertex duplicates
+ */
+template <
+ typename T,
+ typename TVertexIter,
+ typename TGetVertexCoordX,
+ typename TGetVertexCoordY>
+DuplicatesInfo FindDuplicates(
+ TVertexIter first,
+ TVertexIter last,
+ TGetVertexCoordX getX,
+ TGetVertexCoordY getY);
+
+/**
+ * Remove duplicates in-place from vector of custom points
+ * @tparam TVertex vertex type
+ * @tparam TAllocator allocator used by input vector of vertices
+ * @param vertices vertices to remove duplicates from
+ * @param duplicates information about duplicates
+ */
+template
+void RemoveDuplicates(
+ std::vector& vertices,
+ const std::vector& duplicates);
+
+/**
+ * Remove duplicated points in-place
+ *
+ * @tparam T type of vertex coordinates (e.g., float, double)
+ * @param[in, out] vertices collection of vertices to remove duplicates from
+ * @returns information about duplicated vertices that were removed.
+ */
+template
+CDT_EXPORT DuplicatesInfo RemoveDuplicates(std::vector >& vertices);
+
+/**
+ * Remap vertex indices in edges (in-place) using given vertex-index mapping.
+ * @tparam TEdgeIter iterator that dereferences to custom edge type
+ * @tparam TGetEdgeVertexStart function object getting start vertex index
+ * from an edge.
+ * Getter signature: const TEdgeIter::value_type& -> CDT::VertInd
+ * @tparam TGetEdgeVertexEnd function object getting end vertex index from
+ * an edge. Getter signature: const TEdgeIter::value_type& -> CDT::VertInd
+ * @tparam TMakeEdgeFromStartAndEnd function object that makes new edge from
+ * start and end vertices
+ * @param first beginning of the range of edges
+ * @param last end of the range of edges
+ * @param mapping vertex-index mapping
+ * @param getStart getter of edge start vertex index
+ * @param getEnd getter of edge end vertex index
+ * @param makeEdge factory for making edge from vetices
+ */
+template <
+ typename TEdgeIter,
+ typename TGetEdgeVertexStart,
+ typename TGetEdgeVertexEnd,
+ typename TMakeEdgeFromStartAndEnd>
+CDT_EXPORT void RemapEdges(
+ TEdgeIter first,
+ TEdgeIter last,
+ const std::vector& mapping,
+ TGetEdgeVertexStart getStart,
+ TGetEdgeVertexEnd getEnd,
+ TMakeEdgeFromStartAndEnd makeEdge);
+
+/**
+ * Remap vertex indices in edges (in-place) using given vertex-index mapping.
+ *
+ * @note Mapping can be a result of RemoveDuplicates function
+ * @param[in,out] edges collection of edges to remap
+ * @param mapping vertex-index mapping
+ */
+CDT_EXPORT void
+RemapEdges(std::vector& edges, const std::vector& mapping);
+
+/**
+ * Find point duplicates, remove them from vector (in-place) and remap edges
+ * (in-place)
+ * @note Same as a chained call of CDT::FindDuplicates, CDT::RemoveDuplicates,
+ * and CDT::RemapEdges
+ * @tparam T type of vertex coordinates (e.g., float, double)
+ * @tparam TVertex type of vertex
+ * @tparam TGetVertexCoordX function object getting x coordinate from vertex.
+ * Getter signature: const TVertexIter::value_type& -> T
+ * @tparam TGetVertexCoordY function object getting y coordinate from vertex.
+ * Getter signature: const TVertexIter::value_type& -> T
+ * @tparam TEdgeIter iterator that dereferences to custom edge type
+ * @tparam TGetEdgeVertexStart function object getting start vertex index
+ * from an edge.
+ * Getter signature: const TEdgeIter::value_type& -> CDT::VertInd
+ * @tparam TGetEdgeVertexEnd function object getting end vertex index from
+ * an edge. Getter signature: const TEdgeIter::value_type& -> CDT::VertInd
+ * @tparam TMakeEdgeFromStartAndEnd function object that makes new edge from
+ * start and end vertices
+ * @param[in, out] vertices vertices to remove duplicates from
+ * @param[in, out] edges collection of edges connecting vertices
+ * @param getX getter of X-coordinate
+ * @param getY getter of Y-coordinate
+ * @param edgesFirst beginning of the range of edges
+ * @param edgesLast end of the range of edges
+ * @param getStart getter of edge start vertex index
+ * @param getEnd getter of edge end vertex index
+ * @param makeEdge factory for making edge from vetices
+ * @returns information about vertex duplicates
+ */
+template <
+ typename T,
+ typename TVertex,
+ typename TGetVertexCoordX,
+ typename TGetVertexCoordY,
+ typename TVertexAllocator,
+ typename TEdgeIter,
+ typename TGetEdgeVertexStart,
+ typename TGetEdgeVertexEnd,
+ typename TMakeEdgeFromStartAndEnd>
+DuplicatesInfo RemoveDuplicatesAndRemapEdges(
+ std::vector& vertices,
+ TGetVertexCoordX getX,
+ TGetVertexCoordY getY,
+ TEdgeIter edgesFirst,
+ TEdgeIter edgesLast,
+ TGetEdgeVertexStart getStart,
+ TGetEdgeVertexEnd getEnd,
+ TMakeEdgeFromStartAndEnd makeEdge);
+
+/**
+ * Same as a chained call of CDT::RemoveDuplicates + CDT::RemapEdges
+ *
+ * @tparam T type of vertex coordinates (e.g., float, double)
+ * @param[in, out] vertices collection of vertices to remove duplicates from
+ * @param[in,out] edges collection of edges to remap
+ */
+template
+CDT_EXPORT DuplicatesInfo RemoveDuplicatesAndRemapEdges(
+ std::vector >& vertices,
+ std::vector& edges);
+
+/**
+ * Extract all edges of triangles
+ *
+ * @param triangles triangles used to extract edges
+ * @return an unordered set of all edges of triangulation
+ */
+CDT_EXPORT EdgeUSet extractEdgesFromTriangles(const TriangleVec& triangles);
+
+/*!
+ * Converts piece->original_edges mapping to original_edge->pieces
+ * @param pieceToOriginals maps pieces to original edges
+ * @return mapping of original edges to pieces
+ */
+CDT_EXPORT unordered_map
+EdgeToPiecesMapping(const unordered_map& pieceToOriginals);
+
+/*!
+ * Convert edge-to-pieces mapping into edge-to-split-vertices mapping
+ * @tparam T type of vertex coordinates (e.g., float, double)
+ * @param edgeToPieces edge-to-pieces mapping
+ * @param vertices vertex buffer
+ * @return mapping of edge-to-split-points.
+ * Split points are sorted from edge's start (v1) to end (v2)
+ */
+template
+CDT_EXPORT unordered_map > EdgeToSplitVertices(
+ const unordered_map& edgeToPieces,
+ const std::vector >& vertices);
+
+/// @}
+
+/// @}
+
+} // namespace CDT
+
+//*****************************************************************************
+// Implementations of template functionlity
+//*****************************************************************************
+// hash for CDT::V2d
+#ifdef CDT_CXX11_IS_SUPPORTED
+namespace std
+#else
+namespace boost
+#endif
+{
+template
+struct hash >
+{
+ size_t operator()(const CDT::V2d& xy) const
+ {
+#ifdef CDT_CXX11_IS_SUPPORTED
+ typedef std::hash Hasher;
+#else
+ typedef boost::hash Hasher;
+#endif
+ return Hasher()(xy.x) ^ Hasher()(xy.y);
+ }
+};
+} // namespace std
+
+namespace CDT
+{
+
+//-----
+// API
+//-----
+template <
+ typename T,
+ typename TVertexIter,
+ typename TGetVertexCoordX,
+ typename TGetVertexCoordY>
+DuplicatesInfo FindDuplicates(
+ TVertexIter first,
+ TVertexIter last,
+ TGetVertexCoordX getX,
+ TGetVertexCoordY getY)
+{
+ typedef unordered_map, std::size_t> PosToIndex;
+ PosToIndex uniqueVerts;
+ const std::size_t verticesSize = std::distance(first, last);
+ DuplicatesInfo di = {
+ std::vector(verticesSize), std::vector()};
+ for(std::size_t iIn = 0, iOut = iIn; iIn < verticesSize; ++iIn, ++first)
+ {
+ typename PosToIndex::const_iterator it;
+ bool isUnique;
+ tie(it, isUnique) = uniqueVerts.insert(
+ std::make_pair(V2d::make(getX(*first), getY(*first)), iOut));
+ if(isUnique)
+ {
+ di.mapping[iIn] = iOut++;
+ continue;
+ }
+ di.mapping[iIn] = it->second; // found a duplicate
+ di.duplicates.push_back(iIn);
+ }
+ return di;
+}
+
+template
+void RemoveDuplicates(
+ std::vector& vertices,
+ const std::vector& duplicates)
+{
+ vertices.erase(
+ remove_at(
+ vertices.begin(),
+ vertices.end(),
+ duplicates.begin(),
+ duplicates.end()),
+ vertices.end());
+}
+
+template <
+ typename TEdgeIter,
+ typename TGetEdgeVertexStart,
+ typename TGetEdgeVertexEnd,
+ typename TMakeEdgeFromStartAndEnd>
+void RemapEdges(
+ TEdgeIter first,
+ const TEdgeIter last,
+ const std::vector& mapping,
+ TGetEdgeVertexStart getStart,
+ TGetEdgeVertexEnd getEnd,
+ TMakeEdgeFromStartAndEnd makeEdge)
+{
+ for(; first != last; ++first)
+ {
+ *first = makeEdge(
+ static_cast(mapping[getStart(*first)]),
+ static_cast(mapping[getEnd(*first)]));
+ }
+}
+
+template <
+ typename T,
+ typename TVertex,
+ typename TGetVertexCoordX,
+ typename TGetVertexCoordY,
+ typename TVertexAllocator,
+ typename TEdgeIter,
+ typename TGetEdgeVertexStart,
+ typename TGetEdgeVertexEnd,
+ typename TMakeEdgeFromStartAndEnd>
+DuplicatesInfo RemoveDuplicatesAndRemapEdges(
+ std::vector& vertices,
+ TGetVertexCoordX getX,
+ TGetVertexCoordY getY,
+ const TEdgeIter edgesFirst,
+ const TEdgeIter edgesLast,
+ TGetEdgeVertexStart getStart,
+ TGetEdgeVertexEnd getEnd,
+ TMakeEdgeFromStartAndEnd makeEdge)
+{
+ const DuplicatesInfo di =
+ FindDuplicates(vertices.begin(), vertices.end(), getX, getY);
+ RemoveDuplicates(vertices, di.duplicates);
+ RemapEdges(edgesFirst, edgesLast, di.mapping, getStart, getEnd, makeEdge);
+ return di;
+}
+
+template
+unordered_map > EdgeToSplitVertices(
+ const unordered_map& edgeToPieces,
+ const std::vector >& vertices)
+{
+ typedef std::pair VertCoordPair;
+ struct ComparePred
+ {
+ bool operator()(const VertCoordPair& a, const VertCoordPair& b) const
+ {
+ return a.second < b.second;
+ }
+ } comparePred;
+
+ unordered_map > edgeToSplitVerts;
+ typedef unordered_map::const_iterator It;
+ for(It e2pIt = edgeToPieces.begin(); e2pIt != edgeToPieces.end(); ++e2pIt)
+ {
+ const Edge& e = e2pIt->first;
+ const T dX = vertices[e.v2()].x - vertices[e.v1()].x;
+ const T dY = vertices[e.v2()].y - vertices[e.v1()].y;
+ const bool isX = std::abs(dX) >= std::abs(dY); // X-coord longer
+ const bool isAscending =
+ isX ? dX >= 0 : dY >= 0; // Longer coordinate ascends
+ const EdgeVec& pieces = e2pIt->second;
+ std::vector splitVerts;
+ // size is: 2[ends] + (pieces - 1)[split vertices] = pieces + 1
+ splitVerts.reserve(pieces.size() + 1);
+ typedef EdgeVec::const_iterator EIt;
+ for(EIt pieceIt = pieces.begin(); pieceIt != pieces.end(); ++pieceIt)
+ {
+ const array vv = {pieceIt->v1(), pieceIt->v2()};
+ typedef array::const_iterator VIt;
+ for(VIt v = vv.begin(); v != vv.end(); ++v)
+ {
+ const T c = isX ? vertices[*v].x : vertices[*v].y;
+ splitVerts.push_back(std::make_pair(*v, isAscending ? c : -c));
+ }
+ }
+ // sort by longest coordinate
+ std::sort(splitVerts.begin(), splitVerts.end(), comparePred);
+ // remove duplicates
+ splitVerts.erase(
+ std::unique(splitVerts.begin(), splitVerts.end()),
+ splitVerts.end());
+ assert(splitVerts.size() > 2); // 2 end points with split vertices
+ std::pair > val =
+ std::make_pair(e, std::vector());
+ val.second.reserve(splitVerts.size());
+ typedef typename std::vector::const_iterator SEIt;
+ for(SEIt it = splitVerts.begin() + 1; it != splitVerts.end() - 1; ++it)
+ {
+ val.second.push_back(it->first);
+ }
+ edgeToSplitVerts.insert(val);
+ }
+ return edgeToSplitVerts;
+}
+
+} // namespace CDT
+
+#ifndef CDT_USE_AS_COMPILED_LIBRARY
+#include "CDT.hpp"
+#endif
+
+#endif // header-guard
diff --git a/Duin/vendor/cdt/CDT/include/CDT.hpp b/Duin/vendor/cdt/CDT/include/CDT.hpp
new file mode 100644
index 0000000..66f9f26
--- /dev/null
+++ b/Duin/vendor/cdt/CDT/include/CDT.hpp
@@ -0,0 +1,107 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+/**
+ * @file
+ * Public API - implementation
+ */
+
+#include "CDT.h"
+
+#include
+#include
+#include
+#include
+
+namespace CDT
+{
+
+CDT_INLINE_IF_HEADER_ONLY VerticesTriangles calculateTrianglesByVertex(
+ const TriangleVec& triangles,
+ const VertInd verticesSize)
+{
+ VerticesTriangles vertTris(verticesSize);
+ for(TriInd iT(0); iT < triangles.size(); ++iT)
+ {
+ const VerticesArr3& vv = triangles[iT].vertices;
+ for(VerticesArr3::const_iterator v = vv.begin(); v != vv.end(); ++v)
+ {
+ vertTris[*v].push_back(iT);
+ }
+ }
+ return vertTris;
+}
+
+template
+DuplicatesInfo RemoveDuplicates(std::vector >& vertices)
+{
+ const DuplicatesInfo di = FindDuplicates(
+ vertices.begin(), vertices.end(), getX_V2d, getY_V2d);
+ RemoveDuplicates(vertices, di.duplicates);
+ return di;
+}
+
+CDT_INLINE_IF_HEADER_ONLY void
+RemapEdges(std::vector& edges, const std::vector& mapping)
+{
+ RemapEdges(
+ edges.begin(),
+ edges.end(),
+ mapping,
+ edge_get_v1,
+ edge_get_v2,
+ edge_make);
+}
+
+template
+DuplicatesInfo RemoveDuplicatesAndRemapEdges(
+ std::vector >& vertices,
+ std::vector& edges)
+{
+ return RemoveDuplicatesAndRemapEdges(
+ vertices,
+ getX_V2d,
+ getY_V2d,
+ edges.begin(),
+ edges.end(),
+ edge_get_v1,
+ edge_get_v2,
+ edge_make);
+}
+
+CDT_INLINE_IF_HEADER_ONLY EdgeUSet
+extractEdgesFromTriangles(const TriangleVec& triangles)
+{
+ EdgeUSet edges;
+ typedef TriangleVec::const_iterator CIt;
+ for(CIt t = triangles.begin(); t != triangles.end(); ++t)
+ {
+ edges.insert(Edge(VertInd(t->vertices[0]), VertInd(t->vertices[1])));
+ edges.insert(Edge(VertInd(t->vertices[1]), VertInd(t->vertices[2])));
+ edges.insert(Edge(VertInd(t->vertices[2]), VertInd(t->vertices[0])));
+ }
+ return edges;
+}
+
+CDT_INLINE_IF_HEADER_ONLY unordered_map
+EdgeToPiecesMapping(const unordered_map& pieceToOriginals)
+{
+ unordered_map originalToPieces;
+ typedef unordered_map::const_iterator Cit;
+ for(Cit ptoIt = pieceToOriginals.begin(); ptoIt != pieceToOriginals.end();
+ ++ptoIt)
+ {
+ const Edge piece = ptoIt->first;
+ const EdgeVec& originals = ptoIt->second;
+ for(EdgeVec::const_iterator origIt = originals.begin();
+ origIt != originals.end();
+ ++origIt)
+ {
+ originalToPieces[*origIt].push_back(piece);
+ }
+ }
+ return originalToPieces;
+}
+
+} // namespace CDT
diff --git a/Duin/vendor/cdt/CDT/include/CDTUtils.h b/Duin/vendor/cdt/CDT/include/CDTUtils.h
new file mode 100644
index 0000000..1b9a0ff
--- /dev/null
+++ b/Duin/vendor/cdt/CDT/include/CDTUtils.h
@@ -0,0 +1,508 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+/**
+ * @file
+ * Utilities and helpers
+ */
+
+#ifndef CDT_obwOaxOTdAWcLNTlNnaq
+#define CDT_obwOaxOTdAWcLNTlNnaq
+
+#ifdef CDT_DONT_USE_BOOST_RTREE
+// CDT_DONT_USE_BOOST_RTREE was replaced with CDT_USE_BOOST
+typedef char CDT_DONT_USE_BOOST_RTREE__was__replaced__with__CDT_USE_BOOST[-1];
+#endif
+
+// #define CDT_USE_STRONG_TYPING // strong type checks on indices
+
+// check if c++11 is supported
+#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900)
+#define CDT_CXX11_IS_SUPPORTED
+#elif !defined(__cplusplus) && !defined(_MSC_VER)
+typedef char couldnt_parse_cxx_standard[-1]; ///< Error: couldn't parse standard
+#endif
+
+// Functions defined outside the class need to be 'inline'
+// if CDT is configured to be used as header-only library:
+// single-definition rule is violated otherwise
+#ifdef CDT_USE_AS_COMPILED_LIBRARY
+#define CDT_INLINE_IF_HEADER_ONLY
+#include "cdt_export.h" // automatically generated by CMake
+#else
+/**
+ * Macro for inlining non-template functions when in header-only mode to
+ * avoid multiple declaration errors.
+ */
+#define CDT_INLINE_IF_HEADER_ONLY inline
+/// Export not needed in header-only mode
+#define CDT_EXPORT
+#endif
+
+#include
+#include
+#include
+#include
+#include
+
+#ifdef CDT_USE_STRONG_TYPING
+#include
+#endif
+
+// use fall-backs for c++11 features
+#ifdef CDT_CXX11_IS_SUPPORTED
+
+#include
+#include
+#include
+#include
+#include
+namespace CDT
+{
+using std::array;
+using std::get;
+using std::make_tuple;
+using std::tie;
+using std::tuple;
+using std::unordered_map;
+using std::unordered_set;
+} // namespace CDT
+
+#else
+#include
+#include
+#include
+#include
+#include
+namespace CDT
+{
+using boost::array;
+using boost::get;
+using boost::make_tuple;
+using boost::tie;
+using boost::tuple;
+using boost::unordered_map;
+using boost::unordered_set;
+} // namespace CDT
+#endif
+
+namespace CDT
+{
+
+/// 2D vector
+template
+struct CDT_EXPORT V2d
+{
+ T x; ///< X-coordinate
+ T y; ///< Y-coordinate
+
+ /// Create vector from X and Y coordinates
+ static V2d make(T x, T y);
+};
+
+/// X- coordinate getter for V2d
+template
+const T& getX_V2d(const V2d& v)
+{
+ return v.x;
+}
+
+/// Y-coordinate getter for V2d
+template
+const T& getY_V2d(const V2d& v)
+{
+ return v.y;
+}
+
+/// If two 2D vectors are exactly equal
+template
+bool operator==(const CDT::V2d& lhs, const CDT::V2d& rhs)
+{
+ return lhs.x == rhs.x && lhs.y == rhs.y;
+}
+
+#ifdef CDT_USE_64_BIT_INDEX_TYPE
+typedef unsigned long long IndexSizeType;
+#else
+typedef unsigned int IndexSizeType;
+#endif
+
+#ifdef CDT_USE_STRONG_TYPING
+/// Index in triangle
+BOOST_STRONG_TYPEDEF(unsigned char, Index);
+/// Vertex index
+BOOST_STRONG_TYPEDEF(IndexSizeType, VertInd);
+/// Triangle index
+BOOST_STRONG_TYPEDEF(IndexSizeType, TriInd);
+#else
+/// Index in triangle
+typedef unsigned char Index;
+/// Vertex index
+typedef IndexSizeType VertInd;
+/// Triangle index
+typedef IndexSizeType TriInd;
+#endif
+
+/// Constant representing no valid value for index
+const static IndexSizeType
+ invalidIndex(std::numeric_limits::max());
+/// Constant representing no valid neighbor for a triangle
+const static TriInd noNeighbor(invalidIndex);
+/// Constant representing no valid vertex for a triangle
+const static VertInd noVertex(invalidIndex);
+
+typedef std::vector TriIndVec; ///< Vector of triangle indices
+typedef array VerticesArr3; ///< array of three vertex indices
+typedef array NeighborsArr3; ///< array of three neighbors
+
+/// 2D bounding box
+template
+struct CDT_EXPORT Box2d
+{
+ V2d min; ///< min box corner
+ V2d max; ///< max box corner
+
+ /// Envelop box around a point
+ void envelopPoint(const V2d& p)
+ {
+ envelopPoint(p.x, p.y);
+ }
+ /// Envelop box around a point with given coordinates
+ void envelopPoint(const T x, const T y)
+ {
+ min.x = std::min(x, min.x);
+ max.x = std::max(x, max.x);
+ min.y = std::min(y, min.y);
+ max.y = std::max(y, max.y);
+ }
+};
+
+/// Bounding box of a collection of custom 2D points given coordinate getters
+template <
+ typename T,
+ typename TVertexIter,
+ typename TGetVertexCoordX,
+ typename TGetVertexCoordY>
+Box2d envelopBox(
+ TVertexIter first,
+ TVertexIter last,
+ TGetVertexCoordX getX,
+ TGetVertexCoordY getY)
+{
+ const T max = std::numeric_limits::max();
+ Box2d box = {{max, max}, {-max, -max}};
+ for(; first != last; ++first)
+ {
+ box.envelopPoint(getX(*first), getY(*first));
+ }
+ return box;
+}
+
+/// Bounding box of a collection of 2D points
+template
+CDT_EXPORT Box2d envelopBox(const std::vector >& vertices);
+
+/// Edge connecting two vertices: vertex with smaller index is always first
+/// \note: hash Edge is specialized at the bottom
+struct CDT_EXPORT Edge
+{
+ /// Constructor
+ Edge(VertInd iV1, VertInd iV2);
+ /// Equals operator
+ bool operator==(const Edge& other) const;
+ /// Not-equals operator
+ bool operator!=(const Edge& other) const;
+ /// V1 getter
+ VertInd v1() const;
+ /// V2 getter
+ VertInd v2() const;
+ /// Edges' vertices
+ const std::pair& verts() const;
+
+private:
+ std::pair m_vertices;
+};
+
+/// Get edge first vertex
+inline VertInd edge_get_v1(const Edge& e)
+{
+ return e.v1();
+}
+
+/// Get edge second vertex
+inline VertInd edge_get_v2(const Edge& e)
+{
+ return e.v2();
+}
+
+/// Get edge second vertex
+inline Edge edge_make(VertInd iV1, VertInd iV2)
+{
+ return Edge(iV1, iV2);
+}
+
+typedef std::vector EdgeVec; ///< Vector of edges
+typedef unordered_set EdgeUSet; ///< Hash table of edges
+typedef unordered_set TriIndUSet; ///< Hash table of triangles
+typedef unordered_map TriIndUMap; ///< Triangle hash map
+
+/// Triangulation triangle (counter-clockwise winding)
+/*
+ * v3
+ * /\
+ * n3/ \n2
+ * /____\
+ * v1 n1 v2
+ */
+struct CDT_EXPORT Triangle
+{
+ VerticesArr3 vertices; ///< triangle's three vertices
+ NeighborsArr3 neighbors; ///< triangle's three neighbors
+
+ /**
+ * Factory method
+ * @note needed for c++03 compatibility (no uniform initialization
+ * available)
+ */
+ static Triangle
+ make(const array& vertices, const array& neighbors)
+ {
+ Triangle t = {vertices, neighbors};
+ return t;
+ }
+
+ /// Next triangle adjacent to a vertex (clockwise)
+ /// @returns pair of next triangle and the other vertex of a common edge
+ std::pair next(const VertInd i) const
+ {
+ assert(vertices[0] == i || vertices[1] == i || vertices[2] == i);
+ if(vertices[0] == i)
+ {
+ return std::make_pair(neighbors[0], vertices[1]);
+ }
+ if(vertices[1] == i)
+ {
+ return std::make_pair(neighbors[1], vertices[2]);
+ }
+ return std::make_pair(neighbors[2], vertices[0]);
+ }
+ /// Previous triangle adjacent to a vertex (counter-clockwise)
+ /// @returns pair of previous triangle and the other vertex of a common edge
+ std::pair prev(const VertInd i) const
+ {
+ assert(vertices[0] == i || vertices[1] == i || vertices[2] == i);
+ if(vertices[0] == i)
+ return std::make_pair(neighbors[2], vertices[2]);
+ if(vertices[1] == i)
+ return std::make_pair(neighbors[0], vertices[0]);
+ return std::make_pair(neighbors[1], vertices[1]);
+ }
+
+ bool containsVertex(const VertInd i) const
+ {
+ return std::find(vertices.begin(), vertices.end(), i) != vertices.end();
+ }
+};
+
+typedef std::vector TriangleVec; ///< Vector of triangles
+
+/// Advance vertex or neighbor index counter-clockwise
+CDT_EXPORT Index ccw(Index i);
+
+/// Advance vertex or neighbor index clockwise
+CDT_EXPORT Index cw(Index i);
+
+/// Location of point on a triangle
+struct CDT_EXPORT PtTriLocation
+{
+ /// Enum
+ enum Enum
+ {
+ Inside,
+ Outside,
+ OnEdge1,
+ OnEdge2,
+ OnEdge3,
+ OnVertex,
+ };
+};
+
+/// Check if location is classified as on any of three edges
+CDT_EXPORT bool isOnEdge(PtTriLocation::Enum location);
+
+/// Neighbor index from a on-edge location
+/// \note Call only if located on the edge!
+CDT_EXPORT Index edgeNeighbor(PtTriLocation::Enum location);
+
+/// Relative location of point to a line
+struct CDT_EXPORT PtLineLocation
+{
+ /// Enum
+ enum Enum
+ {
+ Left,
+ Right,
+ OnLine,
+ };
+};
+
+/// Orient p against line v1-v2 2D: robust geometric predicate
+template
+CDT_EXPORT T orient2D(const V2d& p, const V2d& v1, const V2d& v2);
+
+/// Check if point lies to the left of, to the right of, or on a line
+template
+CDT_EXPORT PtLineLocation::Enum locatePointLine(
+ const V2d& p,
+ const V2d& v1,
+ const V2d& v2,
+ T orientationTolerance = T(0));
+
+/// Classify value of orient2d predicate
+template
+CDT_EXPORT PtLineLocation::Enum
+classifyOrientation(T orientation, T orientationTolerance = T(0));
+
+/// Check if point a lies inside of, outside of, or on an edge of a triangle
+template
+CDT_EXPORT PtTriLocation::Enum locatePointTriangle(
+ const V2d& p,
+ const V2d& v1,
+ const V2d& v2,
+ const V2d& v3);
+
+/// Opposed neighbor index from vertex index
+CDT_EXPORT CDT_INLINE_IF_HEADER_ONLY Index opoNbr(Index vertIndex);
+
+/// Opposed vertex index from neighbor index
+CDT_EXPORT CDT_INLINE_IF_HEADER_ONLY Index opoVrt(Index neighborIndex);
+
+/// Index of triangle's neighbor opposed to a vertex
+CDT_EXPORT CDT_INLINE_IF_HEADER_ONLY Index
+opposedTriangleInd(const VerticesArr3& vv, VertInd iVert);
+
+/// Index of triangle's neighbor opposed to an edge
+CDT_INLINE_IF_HEADER_ONLY Index
+edgeNeighborInd(const VerticesArr3& vv, VertInd iVedge1, VertInd iVedge2);
+
+/// Index of triangle's vertex opposed to a triangle
+CDT_EXPORT CDT_INLINE_IF_HEADER_ONLY Index
+opposedVertexInd(const NeighborsArr3& nn, TriInd iTopo);
+
+/// If triangle has a given vertex return vertex-index
+CDT_EXPORT CDT_INLINE_IF_HEADER_ONLY Index
+vertexInd(const VerticesArr3& vv, VertInd iV);
+
+/// Given triangle and a vertex find opposed triangle
+CDT_EXPORT CDT_INLINE_IF_HEADER_ONLY TriInd
+opposedTriangle(const Triangle& tri, VertInd iVert);
+
+/// Given triangle and an edge find neighbor sharing the edge
+CDT_EXPORT CDT_INLINE_IF_HEADER_ONLY TriInd
+edgeNeighbor(const Triangle& tri, VertInd iVedge1, VertInd iVedge2);
+
+/// Given two triangles, return vertex of first triangle opposed to the second
+CDT_EXPORT CDT_INLINE_IF_HEADER_ONLY VertInd
+opposedVertex(const Triangle& tri, TriInd iTopo);
+
+/// Test if point lies in a circumscribed circle of a triangle
+template
+CDT_EXPORT bool isInCircumcircle(
+ const V2d& p,
+ const V2d& v1,
+ const V2d& v2,
+ const V2d& v3);
+
+/// Test if two vertices share at least one common triangle
+CDT_EXPORT CDT_INLINE_IF_HEADER_ONLY bool
+verticesShareEdge(const TriIndVec& aTris, const TriIndVec& bTris);
+
+/// Distance between two 2D points
+template
+CDT_EXPORT T distance(const V2d& a, const V2d& b);
+
+/// Squared distance between two 2D points
+template
+CDT_EXPORT T distanceSquared(const V2d& a, const V2d& b);
+
+/// Check if any of triangle's vertices belongs to a super-triangle
+CDT_INLINE_IF_HEADER_ONLY bool touchesSuperTriangle(const Triangle& t);
+
+} // namespace CDT
+
+#ifndef CDT_USE_AS_COMPILED_LIBRARY
+#include "CDTUtils.hpp"
+#endif
+
+//*****************************************************************************
+// Specialize hash functions
+//*****************************************************************************
+#ifdef CDT_CXX11_IS_SUPPORTED
+namespace std
+#else
+namespace boost
+#endif
+{
+
+#ifdef CDT_USE_STRONG_TYPING
+
+/// Vertex index hasher
+template <>
+struct hash
+{
+ /// Hash operator
+ std::size_t operator()(const CDT::VertInd& vi) const
+ {
+ return std::hash()(vi.t);
+ }
+};
+
+/// Triangle index hasher
+template <>
+struct hash
+{
+ /// Hash operator
+ std::size_t operator()(const CDT::TriInd& vi) const
+ {
+ return std::hash()(vi.t);
+ }
+};
+
+#endif // CDT_USE_STRONG_TYPING
+
+/// Edge hasher
+template <>
+struct hash
+{
+ /// Hash operator
+ std::size_t operator()(const CDT::Edge& e) const
+ {
+ return hashEdge(e);
+ }
+
+private:
+ static void hashCombine(std::size_t& seed, const CDT::VertInd& key)
+ {
+#ifdef CDT_CXX11_IS_SUPPORTED
+ typedef std::hash Hasher;
+#else
+ typedef boost::hash Hasher;
+#endif
+ seed ^= Hasher()(key) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
+ }
+ static std::size_t hashEdge(const CDT::Edge& e)
+ {
+ const std::pair& vv = e.verts();
+ std::size_t seed1(0);
+ hashCombine(seed1, vv.first);
+ hashCombine(seed1, vv.second);
+ std::size_t seed2(0);
+ hashCombine(seed2, vv.second);
+ hashCombine(seed2, vv.first);
+ return std::min(seed1, seed2);
+ }
+};
+} // namespace std/boost
+
+#endif // header guard
diff --git a/Duin/vendor/cdt/CDT/include/CDTUtils.hpp b/Duin/vendor/cdt/CDT/include/CDTUtils.hpp
new file mode 100644
index 0000000..001098a
--- /dev/null
+++ b/Duin/vendor/cdt/CDT/include/CDTUtils.hpp
@@ -0,0 +1,318 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+/**
+ * @file
+ * Utilities and helpers - implementation
+ */
+
+#include "CDTUtils.h"
+
+#include "predicates.h" // robust predicates: orient, in-circle
+
+#include
+
+namespace CDT
+{
+
+//*****************************************************************************
+// V2d
+//*****************************************************************************
+template
+V2d V2d::make(const T x, const T y)
+{
+ V2d out = {x, y};
+ return out;
+}
+
+//*****************************************************************************
+// Box2d
+//*****************************************************************************
+template
+Box2d envelopBox(const std::vector >& vertices)
+{
+ return envelopBox(
+ vertices.begin(), vertices.end(), getX_V2d, getY_V2d);
+}
+
+//*****************************************************************************
+// Edge
+//*****************************************************************************
+CDT_INLINE_IF_HEADER_ONLY Edge::Edge(VertInd iV1, VertInd iV2)
+ : m_vertices(
+ iV1 < iV2 ? std::make_pair(iV1, iV2) : std::make_pair(iV2, iV1))
+{}
+
+CDT_INLINE_IF_HEADER_ONLY bool Edge::operator==(const Edge& other) const
+{
+ return m_vertices == other.m_vertices;
+}
+
+CDT_INLINE_IF_HEADER_ONLY bool Edge::operator!=(const Edge& other) const
+{
+ return !(this->operator==(other));
+}
+
+CDT_INLINE_IF_HEADER_ONLY VertInd Edge::v1() const
+{
+ return m_vertices.first;
+}
+
+CDT_INLINE_IF_HEADER_ONLY VertInd Edge::v2() const
+{
+ return m_vertices.second;
+}
+
+CDT_INLINE_IF_HEADER_ONLY const std::pair& Edge::verts() const
+{
+ return m_vertices;
+}
+
+//*****************************************************************************
+// Utility functions
+//*****************************************************************************
+CDT_INLINE_IF_HEADER_ONLY Index ccw(Index i)
+{
+ return Index((i + 1) % 3);
+}
+
+CDT_INLINE_IF_HEADER_ONLY Index cw(Index i)
+{
+ return Index((i + 2) % 3);
+}
+
+CDT_INLINE_IF_HEADER_ONLY bool isOnEdge(const PtTriLocation::Enum location)
+{
+ return location == PtTriLocation::OnEdge1 ||
+ location == PtTriLocation::OnEdge2 ||
+ location == PtTriLocation::OnEdge3;
+}
+
+CDT_INLINE_IF_HEADER_ONLY Index edgeNeighbor(const PtTriLocation::Enum location)
+{
+ assert(isOnEdge(location));
+ return static_cast(location - PtTriLocation::OnEdge1);
+}
+
+template
+T orient2D(const V2d& p, const V2d& v1, const V2d& v2)
+{
+ return predicates::adaptive::orient2d(v1.x, v1.y, v2.x, v2.y, p.x, p.y);
+}
+
+template
+PtLineLocation::Enum locatePointLine(
+ const V2d& p,
+ const V2d& v1,
+ const V2d& v2,
+ const T orientationTolerance)
+{
+ return classifyOrientation(orient2D(p, v1, v2), orientationTolerance);
+}
+
+template
+PtLineLocation::Enum
+classifyOrientation(const T orientation, const T orientationTolerance)
+{
+ if(orientation < -orientationTolerance)
+ return PtLineLocation::Right;
+ if(orientation > orientationTolerance)
+ return PtLineLocation::Left;
+ return PtLineLocation::OnLine;
+}
+
+template
+PtTriLocation::Enum locatePointTriangle(
+ const V2d& p,
+ const V2d& v1,
+ const V2d& v2,
+ const V2d& v3)
+{
+ using namespace predicates::adaptive;
+ PtTriLocation::Enum result = PtTriLocation::Inside;
+ PtLineLocation::Enum edgeCheck = locatePointLine(p, v1, v2);
+ if(edgeCheck == PtLineLocation::Right)
+ return PtTriLocation::Outside;
+ if(edgeCheck == PtLineLocation::OnLine)
+ result = PtTriLocation::OnEdge1;
+ edgeCheck = locatePointLine(p, v2, v3);
+ if(edgeCheck == PtLineLocation::Right)
+ return PtTriLocation::Outside;
+ if(edgeCheck == PtLineLocation::OnLine)
+ {
+ result = (result == PtTriLocation::Inside) ? PtTriLocation::OnEdge2
+ : PtTriLocation::OnVertex;
+ }
+ edgeCheck = locatePointLine(p, v3, v1);
+ if(edgeCheck == PtLineLocation::Right)
+ return PtTriLocation::Outside;
+ if(edgeCheck == PtLineLocation::OnLine)
+ {
+ result = (result == PtTriLocation::Inside) ? PtTriLocation::OnEdge3
+ : PtTriLocation::OnVertex;
+ }
+ return result;
+}
+
+CDT_INLINE_IF_HEADER_ONLY Index opoNbr(const Index vertIndex)
+{
+ if(vertIndex == Index(0))
+ return Index(1);
+ if(vertIndex == Index(1))
+ return Index(2);
+ if(vertIndex == Index(2))
+ return Index(0);
+ assert(false && "Invalid vertex index");
+ throw std::runtime_error("Invalid vertex index");
+}
+
+CDT_INLINE_IF_HEADER_ONLY Index opoVrt(const Index neighborIndex)
+{
+ if(neighborIndex == Index(0))
+ return Index(2);
+ if(neighborIndex == Index(1))
+ return Index(0);
+ if(neighborIndex == Index(2))
+ return Index(1);
+ assert(false && "Invalid neighbor index");
+ throw std::runtime_error("Invalid neighbor index");
+}
+
+CDT_INLINE_IF_HEADER_ONLY Index
+opposedTriangleInd(const VerticesArr3& vv, const VertInd iVert)
+{
+ assert(vv[0] == iVert || vv[1] == iVert || vv[2] == iVert);
+ if(vv[0] == iVert)
+ return Index(1);
+ if(vv[1] == iVert)
+ return Index(2);
+ return Index(0);
+}
+
+CDT_INLINE_IF_HEADER_ONLY Index edgeNeighborInd(
+ const VerticesArr3& vv,
+ const VertInd iVedge1,
+ const VertInd iVedge2)
+{
+ assert(vv[0] == iVedge1 || vv[1] == iVedge1 || vv[2] == iVedge1);
+ assert(vv[0] == iVedge2 || vv[1] == iVedge2 || vv[2] == iVedge2);
+ assert(
+ (vv[0] != iVedge1 && vv[0] != iVedge2) ||
+ (vv[1] != iVedge1 && vv[1] != iVedge2) ||
+ (vv[2] != iVedge1 && vv[2] != iVedge2));
+ /*
+ * vv[2]
+ * /\
+ * n[2]/ \n[1]
+ * /____\
+ * vv[0] n[0] vv[1]
+ */
+ if(vv[0] == iVedge1)
+ {
+ if(vv[1] == iVedge2)
+ return Index(0);
+ return Index(2);
+ }
+ if(vv[0] == iVedge2)
+ {
+ if(vv[1] == iVedge1)
+ return Index(0);
+ return Index(2);
+ }
+ return Index(1);
+}
+
+CDT_INLINE_IF_HEADER_ONLY Index
+opposedVertexInd(const NeighborsArr3& nn, const TriInd iTopo)
+{
+ assert(nn[0] == iTopo || nn[1] == iTopo || nn[2] == iTopo);
+ if(nn[0] == iTopo)
+ return Index(2);
+ if(nn[1] == iTopo)
+ return Index(0);
+ return Index(1);
+}
+
+CDT_INLINE_IF_HEADER_ONLY Index
+vertexInd(const VerticesArr3& vv, const VertInd iV)
+{
+ assert(vv[0] == iV || vv[1] == iV || vv[2] == iV);
+ if(vv[0] == iV)
+ return Index(0);
+ if(vv[1] == iV)
+ return Index(1);
+ return Index(2);
+}
+
+CDT_INLINE_IF_HEADER_ONLY TriInd
+opposedTriangle(const Triangle& tri, const VertInd iVert)
+{
+ return tri.neighbors[opposedTriangleInd(tri.vertices, iVert)];
+}
+
+CDT_INLINE_IF_HEADER_ONLY VertInd
+opposedVertex(const Triangle& tri, const TriInd iTopo)
+{
+ return tri.vertices[opposedVertexInd(tri.neighbors, iTopo)];
+}
+
+/// Given triangle and an edge find neighbor sharing the edge
+CDT_INLINE_IF_HEADER_ONLY TriInd
+edgeNeighbor(const Triangle& tri, VertInd iVedge1, VertInd iVedge2)
+{
+ return tri.neighbors[edgeNeighborInd(tri.vertices, iVedge1, iVedge2)];
+}
+
+template
+bool isInCircumcircle(
+ const V2d& p,
+ const V2d& v1,
+ const V2d& v2,
+ const V2d& v3)
+{
+ using namespace predicates::adaptive;
+ return incircle(v1.x, v1.y, v2.x, v2.y, v3.x, v3.y, p.x, p.y) > T(0);
+}
+
+CDT_INLINE_IF_HEADER_ONLY
+bool verticesShareEdge(const TriIndVec& aTris, const TriIndVec& bTris)
+{
+ for(TriIndVec::const_iterator it = aTris.begin(); it != aTris.end(); ++it)
+ if(std::find(bTris.begin(), bTris.end(), *it) != bTris.end())
+ return true;
+ return false;
+}
+
+template
+T distanceSquared(const T ax, const T ay, const T bx, const T by)
+{
+ const T dx = bx - ax;
+ const T dy = by - ay;
+ return dx * dx + dy * dy;
+}
+
+template
+T distance(const T ax, const T ay, const T bx, const T by)
+{
+ return std::sqrt(distanceSquared(ax, ay, bx, by));
+}
+
+template
+T distance(const V2d& a, const V2d& b)
+{
+ return distance(a.x, a.y, b.x, b.y);
+}
+
+template
+T distanceSquared(const V2d& a, const V2d& b)
+{
+ return distanceSquared(a.x, a.y, b.x, b.y);
+}
+
+bool touchesSuperTriangle(const Triangle& t)
+{
+ return t.vertices[0] < 3 || t.vertices[1] < 3 || t.vertices[2] < 3;
+}
+
+} // namespace CDT
diff --git a/Duin/vendor/cdt/CDT/include/KDTree.h b/Duin/vendor/cdt/CDT/include/KDTree.h
new file mode 100644
index 0000000..2aa4eb2
--- /dev/null
+++ b/Duin/vendor/cdt/CDT/include/KDTree.h
@@ -0,0 +1,412 @@
+/// This Source Code Form is subject to the terms of the Mozilla Public
+/// License, v. 2.0. If a copy of the MPL was not distributed with this
+/// file, You can obtain one at https://mozilla.org/MPL/2.0/.
+/// Contribution of original implementation:
+/// Andre Fecteau
+
+#ifndef KDTREE_KDTREE_H
+#define KDTREE_KDTREE_H
+
+#include "CDTUtils.h"
+
+#include