Working on meshes
This commit is contained in:
parent
c479ccb9e2
commit
7b472fe18d
652 changed files with 81120 additions and 852 deletions
|
|
@ -86,6 +86,7 @@ set(sources "src/main.cpp"
|
|||
"src/DrawingProgram/Tools/EyeDropperTool.cpp"
|
||||
"src/DrawingProgram/Tools/ScreenshotTool.cpp"
|
||||
"src/DrawingProgram/Tools/EditTool.cpp"
|
||||
"src/DrawingProgram/Tools/FillTool.cpp"
|
||||
"src/DrawingProgram/Tools/ZoomCanvasTool.cpp"
|
||||
"src/DrawingProgram/Tools/PanCanvasTool.cpp"
|
||||
"src/DrawingProgram/Tools/GridModifyTool.cpp"
|
||||
|
|
@ -95,7 +96,7 @@ set(sources "src/main.cpp"
|
|||
"src/DrawingProgram/Tools/EditTools/EllipseDrawEditTool.cpp"
|
||||
"src/DrawingProgram/Tools/EditTools/RectDrawEditTool.cpp"
|
||||
"src/DrawingProgram/Tools/EditTools/TextBoxEditTool.cpp"
|
||||
"src/DrawingProgram/Tools/EditTools/BrushEditTool.cpp"
|
||||
"src/DrawingProgram/Tools/EditTools/MeshEditTool.cpp"
|
||||
"src/DrawingProgram/Layers/DrawingProgramLayerManagerGUI.cpp"
|
||||
"src/DrawingProgram/Layers/DrawingProgramLayerManager.cpp"
|
||||
"src/DrawingProgram/Layers/DrawingProgramLayerListItem.cpp"
|
||||
|
|
@ -104,11 +105,12 @@ set(sources "src/main.cpp"
|
|||
"src/DrawingProgram/Layers/SerializedBlendMode.cpp"
|
||||
"src/CanvasComponents/CanvasComponentContainer.cpp"
|
||||
"src/CanvasComponents/CanvasComponentAllocator.cpp"
|
||||
"src/CanvasComponents/BrushStrokeCanvasComponent.cpp"
|
||||
"src/CanvasComponents/MeshCanvasComponent.cpp"
|
||||
"src/CanvasComponents/RectangleCanvasComponent.cpp"
|
||||
"src/CanvasComponents/TextBoxCanvasComponent.cpp"
|
||||
"src/CanvasComponents/EllipseCanvasComponent.cpp"
|
||||
"src/CanvasComponents/ImageCanvasComponent.cpp"
|
||||
"src/CanvasComponents/BrushComponentCode.cpp"
|
||||
"src/CanvasComponents/CanvasComponent.cpp"
|
||||
"src/GUIStuff/GUIManager.cpp"
|
||||
"src/GUIStuff/GUIFloatAnimation.cpp"
|
||||
|
|
@ -228,6 +230,7 @@ if((NOT (GRAPHICS_BACKEND STREQUAL "Vulkan")) AND (NOT EMSCRIPTEN) AND LINUX AND
|
|||
endif()
|
||||
|
||||
find_package(zstd REQUIRED)
|
||||
find_package(clipper2 REQUIRED)
|
||||
|
||||
message("Skia root: " ${SKIA_INCLUDE})
|
||||
message("Build type: " ${CMAKE_BUILD_TYPE})
|
||||
|
|
@ -357,7 +360,7 @@ if((NOT EMSCRIPTEN) AND (NOT APPLE) AND (NOT ANDROID))
|
|||
endif()
|
||||
endif()
|
||||
|
||||
target_link_libraries(main zstd::libzstd_static)
|
||||
target_link_libraries(main zstd::libzstd_static Clipper2::clipper2)
|
||||
|
||||
if((NOT EMSCRIPTEN) AND WIN32)
|
||||
target_link_libraries(main dwrite)
|
||||
|
|
|
|||
1
assets/data/icons/RemixIcon/paint-line.svg
Normal file
1
assets/data/icons/RemixIcon/paint-line.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M19.2277 18.7323L20.9955 16.9645L22.7632 18.7323C23.7395 19.7086 23.7395 21.2915 22.7632 22.2678C21.7869 23.2441 20.204 23.2441 19.2277 22.2678C18.2514 21.2915 18.2514 19.7086 19.2277 18.7323ZM8.87861 1.07971L20.1923 12.3934C20.5828 12.7839 20.5828 13.4171 20.1923 13.8076L11.707 22.2929C11.3165 22.6834 10.6833 22.6834 10.2928 22.2929L1.80754 13.8076C1.41702 13.4171 1.41702 12.7839 1.80754 12.3934L9.58572 4.61525L7.4644 2.49393L8.87861 1.07971ZM10.9999 6.02946L3.92886 13.1005L10.9999 20.1716L18.071 13.1005L10.9999 6.02946Z"></path></svg>
|
||||
|
After Width: | Height: | Size: 631 B |
373
assets/data/third_party_licenses/CDT
Normal file
373
assets/data/third_party_licenses/CDT
Normal file
|
|
@ -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.
|
||||
23
assets/data/third_party_licenses/Clipper2
Normal file
23
assets/data/third_party_licenses/Clipper2
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
Permission is hereby granted, free of charge, to any person or organization
|
||||
obtaining a copy of the software and accompanying documentation covered by
|
||||
this license (the "Software") to use, reproduce, display, distribute,
|
||||
execute, and transmit the Software, and to prepare derivative works of the
|
||||
Software, and to permit third-parties to whom the Software is furnished to
|
||||
do so, all subject to the following:
|
||||
|
||||
The copyright notices in the Software and this entire statement, including
|
||||
the above license grant, this restriction and the following disclaimer,
|
||||
must be included in all copies of the Software, in whole or in part, and
|
||||
all derivative works of the Software, unless such copies or derivative
|
||||
works are solely in the form of machine-executable object code generated by
|
||||
a source language processor.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
|
@ -118,6 +118,7 @@ class CompressorRecipe(ConanFile):
|
|||
self.requires("libdatachannel/0.24.0")
|
||||
self.requires("libcurl/8.20.0")
|
||||
|
||||
self.requires("clipper2/2.0.1")
|
||||
self.requires("zstd/1.5.7")
|
||||
self.requires("icu-infinipaint/77.1")
|
||||
|
||||
|
|
|
|||
286
include/CDT/CMakeLists.txt
Normal file
286
include/CDT/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,286 @@
|
|||
cmake_minimum_required(VERSION 3.4...4.0)
|
||||
|
||||
project(
|
||||
"CDT"
|
||||
VERSION 1.4.2
|
||||
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_CALLBACK_HANDLER
|
||||
"If enabled it is possible to provide a callback handler to the triangulation"
|
||||
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)
|
||||
|
||||
option(CDT_DISABLE_EXCEPTIONS
|
||||
"Disables exceptions: instead of throwing the library will call `std::terminate`"
|
||||
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_CALLBACK_HANDLER is ${CDT_ENABLE_CALLBACK_HANDLER}")
|
||||
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}")
|
||||
message(STATUS "CDT_DISABLE_EXCEPTIONS is ${CDT_DISABLE_EXCEPTIONS}")
|
||||
|
||||
# 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}
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
|
||||
)
|
||||
target_sources(
|
||||
${PROJECT_NAME} ${cdt_scope}
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/cdt_export.h>
|
||||
)
|
||||
|
||||
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}
|
||||
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/${dir_}>
|
||||
)
|
||||
endforeach()
|
||||
|
||||
target_include_directories(
|
||||
${PROJECT_NAME} INTERFACE $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
|
||||
|
||||
target_compile_definitions(
|
||||
${PROJECT_NAME}
|
||||
${cdt_scope}
|
||||
$<$<BOOL:${CDT_USE_BOOST}>:CDT_USE_BOOST>
|
||||
$<$<BOOL:${CDT_USE_AS_COMPILED_LIBRARY}>:CDT_USE_AS_COMPILED_LIBRARY>
|
||||
$<$<BOOL:${CDT_USE_64_BIT_INDEX_TYPE}>:CDT_USE_64_BIT_INDEX_TYPE>
|
||||
$<$<BOOL:${CDT_ENABLE_CALLBACK_HANDLER}>:CDT_ENABLE_CALLBACK_HANDLER>
|
||||
$<$<BOOL:${CDT_USE_STRONG_TYPING}>:CDT_USE_STRONG_TYPING>
|
||||
$<$<BOOL:${CDT_DISABLE_EXCEPTIONS}>:CDT_DISABLE_EXCEPTIONS>
|
||||
)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} ${cdt_scope} $<$<BOOL:${CDT_USE_BOOST}>: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
|
||||
$<$<BOOL:${CDT_USE_AS_COMPILED_LIBRARY}>:${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_ENABLE_PREPROCESSING NO)
|
||||
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()
|
||||
373
include/CDT/LICENSE
Normal file
373
include/CDT/LICENSE
Normal file
|
|
@ -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.
|
||||
10
include/CDT/conan_basic_setup.cmake
Normal file
10
include/CDT/conan_basic_setup.cmake
Normal file
|
|
@ -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()
|
||||
66
include/CDT/conanfile.py
Normal file
66
include/CDT/conanfile.py
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
# 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],
|
||||
"enable_callback_handler": [True, False],
|
||||
}
|
||||
default_options = {
|
||||
"shared": False,
|
||||
"use_boost": False,
|
||||
"as_compiled_library": False,
|
||||
"enable_testing": False,
|
||||
"enable_callback_handler": 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.cache_variables["CDT_ENABLE_CALLBACK_HANDLER"] = self.options.enable_callback_handler
|
||||
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)
|
||||
242
include/CDT/extras/InitializeWithGrid.h
Normal file
242
include/CDT/extras/InitializeWithGrid.h
Normal file
|
|
@ -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 <CDT.h>
|
||||
#include <CDTUtils.h>
|
||||
|
||||
#ifdef CDT_CXX11_IS_SUPPORTED
|
||||
#include <algorithm>
|
||||
#endif
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
#include <vector>
|
||||
|
||||
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<TXCoordIter>::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<T>(*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<TriInd>(2 * (i - 1)));
|
||||
vTris.push_back(static_cast<TriInd>(2 * (i - 1) + 1));
|
||||
}
|
||||
// right-up
|
||||
if(ix < xres && iy < yres)
|
||||
{
|
||||
vTris.push_back(static_cast<TriInd>(2 * i));
|
||||
}
|
||||
// left-down
|
||||
if(ix > 0 && iy > 0)
|
||||
{
|
||||
vTris.push_back(static_cast<TriInd>(2 * (i - xres - 1) + 1));
|
||||
}
|
||||
// right-down
|
||||
if(ix < xres && iy > 0)
|
||||
{
|
||||
vTris.push_back(static_cast<TriInd>(2 * (i - xres)));
|
||||
vTris.push_back(static_cast<TriInd>(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 <typename OutputIt>
|
||||
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 <typename T, typename TNearPointLocator>
|
||||
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<T, TNearPointLocator>& out)
|
||||
{
|
||||
std::vector<T> xcoords;
|
||||
std::vector<T> 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<T, TNearPointLocator>& 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<IndexSizeType>(xres),
|
||||
static_cast<IndexSizeType>(yres));
|
||||
out.initializedWithCustomSuperGeometry();
|
||||
}
|
||||
|
||||
} // namespace CDT
|
||||
|
||||
#endif
|
||||
90
include/CDT/extras/VerifyTopology.h
Normal file
90
include/CDT/extras/VerifyTopology.h
Normal file
|
|
@ -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 <CDT.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
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 <typename T, typename TNearPointLocator>
|
||||
inline bool verifyTopology(const CDT::Triangulation<T, TNearPointLocator>& cdt)
|
||||
{
|
||||
// Check if vertices' adjacent triangles contain vertex
|
||||
const VerticesTriangles vertTris = calculateTrianglesByVertex(
|
||||
cdt.triangles, static_cast<VertInd>(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<VertInd, 3>& 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<TriInd, 3>& 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 <typename T, typename TNearPointLocator>
|
||||
inline bool eachVertexHasNeighborTriangle(
|
||||
const CDT::Triangulation<T, TNearPointLocator>& cdt)
|
||||
{
|
||||
for(const auto& vt : cdt.VertTrisInternal())
|
||||
if(vt == noNeighbor)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace CDT
|
||||
|
||||
#endif
|
||||
448
include/CDT/include/CDT.h
Normal file
448
include/CDT/include/CDT.h
Normal file
|
|
@ -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 <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <stack>
|
||||
#include <vector>
|
||||
|
||||
/// 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<TriIndVec> 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<std::size_t> mapping; ///< vertex index mapping
|
||||
std::vector<std::size_t> 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 <typename TVertex, typename TAllocator>
|
||||
void RemoveDuplicates(
|
||||
std::vector<TVertex, TAllocator>& vertices,
|
||||
const std::vector<std::size_t>& 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 <typename T>
|
||||
CDT_EXPORT DuplicatesInfo RemoveDuplicates(std::vector<V2d<T> >& 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>
|
||||
void RemapEdges(
|
||||
TEdgeIter first,
|
||||
TEdgeIter last,
|
||||
const std::vector<std::size_t>& 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<Edge>& edges, const std::vector<std::size_t>& 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<TVertex, TVertexAllocator>& 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 <typename T>
|
||||
CDT_EXPORT DuplicatesInfo RemoveDuplicatesAndRemapEdges(
|
||||
std::vector<V2d<T> >& vertices,
|
||||
std::vector<Edge>& 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<Edge, EdgeVec>
|
||||
EdgeToPiecesMapping(const unordered_map<Edge, EdgeVec>& 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 <typename T>
|
||||
unordered_map<Edge, std::vector<VertInd> > EdgeToSplitVertices(
|
||||
const unordered_map<Edge, EdgeVec>& edgeToPieces,
|
||||
const std::vector<V2d<T> >& vertices);
|
||||
|
||||
/// @}
|
||||
|
||||
/// @}
|
||||
|
||||
} // namespace CDT
|
||||
|
||||
//*****************************************************************************
|
||||
// Implementations of template functionlity
|
||||
//*****************************************************************************
|
||||
// hash for CDT::V2d<T>
|
||||
#ifdef CDT_CXX11_IS_SUPPORTED
|
||||
namespace std
|
||||
#else
|
||||
namespace boost
|
||||
#endif
|
||||
{
|
||||
template <typename T>
|
||||
struct hash<CDT::V2d<T> >
|
||||
{
|
||||
size_t operator()(const CDT::V2d<T>& xy) const
|
||||
{
|
||||
#ifdef CDT_CXX11_IS_SUPPORTED
|
||||
typedef std::hash<T> Hasher;
|
||||
#else
|
||||
typedef boost::hash<T> 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<V2d<T>, std::size_t> PosToIndex;
|
||||
PosToIndex uniqueVerts;
|
||||
const std::size_t verticesSize = std::distance(first, last);
|
||||
DuplicatesInfo di = {
|
||||
std::vector<std::size_t>(verticesSize), std::vector<std::size_t>()};
|
||||
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<T>(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 <typename TVertex, typename TAllocator>
|
||||
void RemoveDuplicates(
|
||||
std::vector<TVertex, TAllocator>& vertices,
|
||||
const std::vector<std::size_t>& 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<std::size_t>& mapping,
|
||||
TGetEdgeVertexStart getStart,
|
||||
TGetEdgeVertexEnd getEnd,
|
||||
TMakeEdgeFromStartAndEnd makeEdge)
|
||||
{
|
||||
for(; first != last; ++first)
|
||||
{
|
||||
*first = makeEdge(
|
||||
static_cast<VertInd>(mapping[getStart(*first)]),
|
||||
static_cast<VertInd>(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<TVertex, TVertexAllocator>& vertices,
|
||||
TGetVertexCoordX getX,
|
||||
TGetVertexCoordY getY,
|
||||
const TEdgeIter edgesFirst,
|
||||
const TEdgeIter edgesLast,
|
||||
TGetEdgeVertexStart getStart,
|
||||
TGetEdgeVertexEnd getEnd,
|
||||
TMakeEdgeFromStartAndEnd makeEdge)
|
||||
{
|
||||
const DuplicatesInfo di =
|
||||
FindDuplicates<T>(vertices.begin(), vertices.end(), getX, getY);
|
||||
RemoveDuplicates(vertices, di.duplicates);
|
||||
RemapEdges(edgesFirst, edgesLast, di.mapping, getStart, getEnd, makeEdge);
|
||||
return di;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
unordered_map<Edge, std::vector<VertInd> > EdgeToSplitVertices(
|
||||
const unordered_map<Edge, EdgeVec>& edgeToPieces,
|
||||
const std::vector<V2d<T> >& vertices)
|
||||
{
|
||||
typedef std::pair<VertInd, T> VertCoordPair;
|
||||
struct ComparePred
|
||||
{
|
||||
bool operator()(const VertCoordPair& a, const VertCoordPair& b) const
|
||||
{
|
||||
return a.second < b.second;
|
||||
}
|
||||
} comparePred;
|
||||
|
||||
unordered_map<Edge, std::vector<VertInd> > edgeToSplitVerts;
|
||||
typedef unordered_map<Edge, EdgeVec>::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<VertCoordPair> 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<VertInd, 2> vv = {pieceIt->v1(), pieceIt->v2()};
|
||||
typedef array<VertInd, 2>::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<Edge, std::vector<VertInd> > val =
|
||||
std::make_pair(e, std::vector<VertInd>());
|
||||
val.second.reserve(splitVerts.size());
|
||||
typedef typename std::vector<VertCoordPair>::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
|
||||
107
include/CDT/include/CDT.hpp
Normal file
107
include/CDT/include/CDT.hpp
Normal file
|
|
@ -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 <algorithm>
|
||||
#include <deque>
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
|
||||
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 <typename T>
|
||||
DuplicatesInfo RemoveDuplicates(std::vector<V2d<T> >& vertices)
|
||||
{
|
||||
const DuplicatesInfo di = FindDuplicates<T>(
|
||||
vertices.begin(), vertices.end(), getX_V2d<T>, getY_V2d<T>);
|
||||
RemoveDuplicates(vertices, di.duplicates);
|
||||
return di;
|
||||
}
|
||||
|
||||
CDT_INLINE_IF_HEADER_ONLY void
|
||||
RemapEdges(std::vector<Edge>& edges, const std::vector<std::size_t>& mapping)
|
||||
{
|
||||
RemapEdges(
|
||||
edges.begin(),
|
||||
edges.end(),
|
||||
mapping,
|
||||
edge_get_v1,
|
||||
edge_get_v2,
|
||||
edge_make);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
DuplicatesInfo RemoveDuplicatesAndRemapEdges(
|
||||
std::vector<V2d<T> >& vertices,
|
||||
std::vector<Edge>& edges)
|
||||
{
|
||||
return RemoveDuplicatesAndRemapEdges<T>(
|
||||
vertices,
|
||||
getX_V2d<T>,
|
||||
getY_V2d<T>,
|
||||
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<Edge, EdgeVec>
|
||||
EdgeToPiecesMapping(const unordered_map<Edge, EdgeVec>& pieceToOriginals)
|
||||
{
|
||||
unordered_map<Edge, EdgeVec> originalToPieces;
|
||||
typedef unordered_map<Edge, EdgeVec>::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
|
||||
592
include/CDT/include/CDTUtils.h
Normal file
592
include/CDT/include/CDTUtils.h
Normal file
|
|
@ -0,0 +1,592 @@
|
|||
/* 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 <algorithm>
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
#include <vector>
|
||||
|
||||
#ifdef CDT_USE_STRONG_TYPING
|
||||
#include <boost/serialization/strong_typedef.hpp>
|
||||
#endif
|
||||
|
||||
// use fall-backs for c++11 features
|
||||
#ifdef CDT_CXX11_IS_SUPPORTED
|
||||
|
||||
#include <array>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
||||
#ifdef CDT_DISABLE_EXCEPTIONS
|
||||
#include <exception>
|
||||
#endif
|
||||
|
||||
namespace CDT
|
||||
{
|
||||
using std::array;
|
||||
using std::get;
|
||||
using std::make_tuple;
|
||||
using std::tie;
|
||||
using std::to_string;
|
||||
using std::tuple;
|
||||
using std::unordered_map;
|
||||
using std::unordered_set;
|
||||
} // namespace CDT
|
||||
|
||||
#else
|
||||
#include <boost/array.hpp>
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include <boost/unordered_set.hpp>
|
||||
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;
|
||||
|
||||
template <typename T>
|
||||
std::string to_string(const T& value)
|
||||
{
|
||||
return boost::lexical_cast<std::string>(value);
|
||||
}
|
||||
} // namespace CDT
|
||||
#endif
|
||||
|
||||
namespace CDT
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
void handleException(const T& error)
|
||||
{
|
||||
#ifdef CDT_DISABLE_EXCEPTIONS
|
||||
std::terminate();
|
||||
#else
|
||||
throw error;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Needed for c++03 compatibility (no uniform initialization available)
|
||||
template <typename T>
|
||||
array<T, 3> arr3(const T& v0, const T& v1, const T& v2)
|
||||
{
|
||||
const array<T, 3> out = {v0, v1, v2};
|
||||
return out;
|
||||
}
|
||||
|
||||
/// Needed for c++03 compatibility (no uniform initialization available)
|
||||
template <typename T>
|
||||
array<T, 3> arr3(const T& v)
|
||||
{
|
||||
const array<T, 3> out = {v, v, v};
|
||||
return out;
|
||||
}
|
||||
|
||||
/// 2D vector
|
||||
template <typename T>
|
||||
struct CDT_EXPORT V2d
|
||||
{
|
||||
T x; ///< X-coordinate
|
||||
T y; ///< Y-coordinate
|
||||
|
||||
/// Vertex with zero coordinates
|
||||
V2d()
|
||||
: x(T(0))
|
||||
, y(T(0))
|
||||
{}
|
||||
|
||||
/// Vertex with given coordinates
|
||||
V2d(const T x, const T y)
|
||||
: x(x)
|
||||
, y(y)
|
||||
{}
|
||||
};
|
||||
|
||||
/// X- coordinate getter for V2d
|
||||
template <typename T>
|
||||
const T& getX_V2d(const V2d<T>& v)
|
||||
{
|
||||
return v.x;
|
||||
}
|
||||
|
||||
/// Y-coordinate getter for V2d
|
||||
template <typename T>
|
||||
const T& getY_V2d(const V2d<T>& v)
|
||||
{
|
||||
return v.y;
|
||||
}
|
||||
|
||||
/// If two 2D vectors are exactly equal
|
||||
template <typename T>
|
||||
bool operator==(const CDT::V2d<T>& lhs, const CDT::V2d<T>& 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 Index invalidIndex(std::numeric_limits<Index>::max());
|
||||
/// Constant representing no valid value for index size
|
||||
const static IndexSizeType
|
||||
invalidIndexSizeType(std::numeric_limits<IndexSizeType>::max());
|
||||
/// Number of super triangle vertices
|
||||
/// @note placed in a constant so that it's easier to find usages in code
|
||||
const static IndexSizeType nSuperTriangleVertices(3);
|
||||
/// Constant representing no valid neighbor for a triangle
|
||||
const static TriInd noNeighbor(invalidIndexSizeType);
|
||||
/// Constant representing no valid vertex for a triangle
|
||||
const static VertInd noVertex(invalidIndexSizeType);
|
||||
|
||||
typedef std::vector<TriInd> TriIndVec; ///< Vector of triangle indices
|
||||
typedef array<VertInd, 3> VerticesArr3; ///< array of three vertex indices
|
||||
typedef array<TriInd, 3> NeighborsArr3; ///< array of three neighbors
|
||||
|
||||
/// 2D bounding box
|
||||
template <typename T>
|
||||
struct CDT_EXPORT Box2d
|
||||
{
|
||||
V2d<T> min; ///< min box corner
|
||||
V2d<T> max; ///< max box corner
|
||||
|
||||
/// Box that doesn't contain any point
|
||||
Box2d()
|
||||
: min(std::numeric_limits<T>::max(), std::numeric_limits<T>::max())
|
||||
, max(-std::numeric_limits<T>::max(), -std::numeric_limits<T>::max())
|
||||
{}
|
||||
|
||||
/// Envelop box around a point
|
||||
Box2d<T>& envelopPoint(const V2d<T>& p)
|
||||
{
|
||||
return envelopPoint(p.x, p.y);
|
||||
}
|
||||
|
||||
/// Envelop box around a point with given coordinates
|
||||
Box2d<T>& 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);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Envelop box around a collection of custom points
|
||||
template <
|
||||
typename TVertexIter,
|
||||
typename TGetVertexCoordX,
|
||||
typename TGetVertexCoordY>
|
||||
Box2d<T>& envelopPoints(
|
||||
TVertexIter first,
|
||||
TVertexIter last,
|
||||
TGetVertexCoordX getX,
|
||||
TGetVertexCoordY getY)
|
||||
{
|
||||
for(; first != last; ++first)
|
||||
{
|
||||
envelopPoint(getX(*first), getY(*first));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Envelop box around a collection of points
|
||||
Box2d<T>& envelopPoints(const std::vector<V2d<T> >& vertices)
|
||||
{
|
||||
return envelopPoints(
|
||||
vertices.begin(), vertices.end(), getX_V2d<T>, getY_V2d<T>);
|
||||
}
|
||||
};
|
||||
|
||||
/// 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(const VertInd iV1, const VertInd iV2)
|
||||
: m_vertices(
|
||||
iV1 < iV2 ? std::make_pair(iV1, iV2) : std::make_pair(iV2, iV1))
|
||||
{}
|
||||
|
||||
/// Equals operator
|
||||
bool operator==(const Edge& other) const
|
||||
{
|
||||
return m_vertices == other.m_vertices;
|
||||
}
|
||||
|
||||
/// Not-equals operator
|
||||
bool operator!=(const Edge& other) const
|
||||
{
|
||||
return !(this->operator==(other));
|
||||
}
|
||||
|
||||
/// V1 getter
|
||||
VertInd v1() const
|
||||
{
|
||||
return m_vertices.first;
|
||||
}
|
||||
|
||||
/// V2 getter
|
||||
VertInd v2() const
|
||||
{
|
||||
return m_vertices.second;
|
||||
}
|
||||
|
||||
/// Edges' vertices
|
||||
const std::pair<VertInd, VertInd>& verts() const
|
||||
{
|
||||
return m_vertices;
|
||||
}
|
||||
|
||||
private:
|
||||
std::pair<VertInd, VertInd> 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<Edge> EdgeVec; ///< Vector of edges
|
||||
typedef unordered_set<Edge> EdgeUSet; ///< Hash table of edges
|
||||
typedef unordered_set<TriInd> TriIndUSet; ///< Hash table of triangles
|
||||
typedef unordered_map<TriInd, TriInd> 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
|
||||
|
||||
/// Triangle with no vertices and no neighbors
|
||||
Triangle()
|
||||
: vertices(arr3(noVertex))
|
||||
, neighbors(arr3(noNeighbor))
|
||||
{}
|
||||
|
||||
/// Triangle with given vertices and neighbors
|
||||
Triangle(const VerticesArr3& vertices, const NeighborsArr3& neighbors)
|
||||
: vertices(vertices)
|
||||
, neighbors(neighbors)
|
||||
{}
|
||||
|
||||
/// Next triangle adjacent to a vertex (clockwise)
|
||||
/// @returns pair of next triangle and the other vertex of a common edge
|
||||
std::pair<TriInd, VertInd> 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<TriInd, VertInd> 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]);
|
||||
}
|
||||
|
||||
/// Check if triangle contains a vertex
|
||||
bool containsVertex(const VertInd i) const
|
||||
{
|
||||
return std::find(vertices.begin(), vertices.end(), i) != vertices.end();
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::vector<Triangle> 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 <typename T>
|
||||
CDT_EXPORT T orient2D(const V2d<T>& p, const V2d<T>& v1, const V2d<T>& v2);
|
||||
|
||||
/// Check if point lies to the left of, to the right of, or on a line
|
||||
template <typename T>
|
||||
CDT_EXPORT PtLineLocation::Enum locatePointLine(
|
||||
const V2d<T>& p,
|
||||
const V2d<T>& v1,
|
||||
const V2d<T>& v2,
|
||||
T orientationTolerance = T(0));
|
||||
|
||||
/// Classify value of orient2d predicate
|
||||
template <typename T>
|
||||
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 <typename T>
|
||||
CDT_EXPORT PtTriLocation::Enum locatePointTriangle(
|
||||
const V2d<T>& p,
|
||||
const V2d<T>& v1,
|
||||
const V2d<T>& v2,
|
||||
const V2d<T>& 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 <typename T>
|
||||
CDT_EXPORT bool isInCircumcircle(
|
||||
const V2d<T>& p,
|
||||
const V2d<T>& v1,
|
||||
const V2d<T>& v2,
|
||||
const V2d<T>& 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 <typename T>
|
||||
CDT_EXPORT T distance(const V2d<T>& a, const V2d<T>& b);
|
||||
|
||||
/// Squared distance between two 2D points
|
||||
template <typename T>
|
||||
CDT_EXPORT T distanceSquared(const V2d<T>& a, const V2d<T>& 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<CDT::VertInd>
|
||||
{
|
||||
/// Hash operator
|
||||
std::size_t operator()(const CDT::VertInd& vi) const
|
||||
{
|
||||
return std::hash<std::size_t>()(vi.t);
|
||||
}
|
||||
};
|
||||
|
||||
/// Triangle index hasher
|
||||
template <>
|
||||
struct hash<CDT::TriInd>
|
||||
{
|
||||
/// Hash operator
|
||||
std::size_t operator()(const CDT::TriInd& vi) const
|
||||
{
|
||||
return std::hash<std::size_t>()(vi.t);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // CDT_USE_STRONG_TYPING
|
||||
|
||||
/// Edge hasher
|
||||
template <>
|
||||
struct hash<CDT::Edge>
|
||||
{
|
||||
/// 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<CDT::VertInd> Hasher;
|
||||
#else
|
||||
typedef boost::hash<CDT::VertInd> Hasher;
|
||||
#endif
|
||||
seed ^= Hasher()(key) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
|
||||
}
|
||||
|
||||
static std::size_t hashEdge(const CDT::Edge& e)
|
||||
{
|
||||
std::size_t seed(0);
|
||||
hashCombine(seed, e.v1());
|
||||
hashCombine(seed, e.v2());
|
||||
return seed;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace std/boost
|
||||
|
||||
#endif // header guard
|
||||
264
include/CDT/include/CDTUtils.hpp
Normal file
264
include/CDT/include/CDTUtils.hpp
Normal file
|
|
@ -0,0 +1,264 @@
|
|||
/* 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 <stdexcept>
|
||||
|
||||
namespace CDT
|
||||
{
|
||||
|
||||
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<Index>(location - PtTriLocation::OnEdge1);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T orient2D(const V2d<T>& p, const V2d<T>& v1, const V2d<T>& v2)
|
||||
{
|
||||
return predicates::adaptive::orient2d(v1.x, v1.y, v2.x, v2.y, p.x, p.y);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
PtLineLocation::Enum locatePointLine(
|
||||
const V2d<T>& p,
|
||||
const V2d<T>& v1,
|
||||
const V2d<T>& v2,
|
||||
const T orientationTolerance)
|
||||
{
|
||||
return classifyOrientation(orient2D(p, v1, v2), orientationTolerance);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
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 <typename T>
|
||||
PtTriLocation::Enum locatePointTriangle(
|
||||
const V2d<T>& p,
|
||||
const V2d<T>& v1,
|
||||
const V2d<T>& v2,
|
||||
const V2d<T>& 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");
|
||||
handleException(std::runtime_error("Invalid vertex index"));
|
||||
return invalidIndex;
|
||||
}
|
||||
|
||||
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");
|
||||
handleException(std::runtime_error("Invalid neighbor index"));
|
||||
return invalidIndex;
|
||||
}
|
||||
|
||||
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 <typename T>
|
||||
bool isInCircumcircle(
|
||||
const V2d<T>& p,
|
||||
const V2d<T>& v1,
|
||||
const V2d<T>& v2,
|
||||
const V2d<T>& 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 <typename T>
|
||||
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 <typename T>
|
||||
T distance(const T ax, const T ay, const T bx, const T by)
|
||||
{
|
||||
return std::sqrt(distanceSquared(ax, ay, bx, by));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T distance(const V2d<T>& a, const V2d<T>& b)
|
||||
{
|
||||
return distance(a.x, a.y, b.x, b.y);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T distanceSquared(const V2d<T>& a, const V2d<T>& 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
|
||||
471
include/CDT/include/KDTree.h
Normal file
471
include/CDT/include/KDTree.h
Normal file
|
|
@ -0,0 +1,471 @@
|
|||
/// 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 <andre.fecteau1@gmail.com>
|
||||
|
||||
#ifndef KDTREE_KDTREE_H
|
||||
#define KDTREE_KDTREE_H
|
||||
|
||||
#include "CDTUtils.h"
|
||||
|
||||
#include <limits>
|
||||
|
||||
namespace CDT
|
||||
{
|
||||
namespace KDTree
|
||||
{
|
||||
|
||||
struct NodeSplitDirection
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
X,
|
||||
Y,
|
||||
};
|
||||
};
|
||||
|
||||
/// Simple tree structure with alternating half splitting nodes
|
||||
/// @details Simple tree structure
|
||||
/// - Tree to incrementally add points to the structure.
|
||||
/// - Get the nearest point to a given input.
|
||||
/// - Does not check for duplicates, expect unique points.
|
||||
/// @tparam TCoordType type used for storing point coordinate.
|
||||
/// @tparam NumVerticesInLeaf The number of points per leaf.
|
||||
/// @tparam InitialStackDepth initial size of stack depth for nearest query.
|
||||
/// Should be at least 1.
|
||||
/// @tparam StackDepthIncrement increment of stack depth for nearest query when
|
||||
/// stack depth is reached.
|
||||
template <
|
||||
typename TCoordType,
|
||||
size_t NumVerticesInLeaf,
|
||||
size_t InitialStackDepth,
|
||||
size_t StackDepthIncrement>
|
||||
class KDTree
|
||||
{
|
||||
public:
|
||||
typedef TCoordType coord_type;
|
||||
typedef CDT::V2d<coord_type> point_type;
|
||||
typedef CDT::VertInd point_index;
|
||||
typedef std::pair<point_type, point_index> value_type;
|
||||
typedef std::vector<point_index> point_data_vec;
|
||||
typedef point_data_vec::const_iterator pd_cit;
|
||||
typedef CDT::VertInd node_index;
|
||||
typedef CDT::array<node_index, 2> children_type;
|
||||
|
||||
/// Stores kd-tree node data
|
||||
struct Node
|
||||
{
|
||||
children_type children; ///< two children if not leaf; {0,0} if leaf
|
||||
point_data_vec data; ///< points' data if leaf
|
||||
/// Create empty leaf
|
||||
Node()
|
||||
{
|
||||
setChildren(node_index(0), node_index(0));
|
||||
data.reserve(NumVerticesInLeaf);
|
||||
}
|
||||
/// Children setter for convenience
|
||||
void setChildren(const node_index c1, const node_index c2)
|
||||
{
|
||||
children[0] = c1;
|
||||
children[1] = c2;
|
||||
}
|
||||
/// Check if node is a leaf (has no valid children)
|
||||
bool isLeaf() const
|
||||
{
|
||||
return children[0] == children[1];
|
||||
}
|
||||
};
|
||||
|
||||
/// Default constructor
|
||||
KDTree()
|
||||
: m_rootDir(NodeSplitDirection::X)
|
||||
, m_min(point_type(
|
||||
-std::numeric_limits<coord_type>::max(),
|
||||
-std::numeric_limits<coord_type>::max()))
|
||||
, m_max(point_type(
|
||||
std::numeric_limits<coord_type>::max(),
|
||||
std::numeric_limits<coord_type>::max()))
|
||||
, m_size(0)
|
||||
, m_isRootBoxInitialized(false)
|
||||
, m_tasksStack(InitialStackDepth, NearestTask())
|
||||
{
|
||||
m_root = addNewNode();
|
||||
}
|
||||
|
||||
/// Constructor with bounding box known in advance
|
||||
KDTree(const point_type& min, const point_type& max)
|
||||
: m_rootDir(NodeSplitDirection::X)
|
||||
, m_min(min)
|
||||
, m_max(max)
|
||||
, m_size(0)
|
||||
, m_isRootBoxInitialized(true)
|
||||
, m_tasksStack(InitialStackDepth, NearestTask())
|
||||
{
|
||||
m_root = addNewNode();
|
||||
}
|
||||
|
||||
CDT::VertInd size() const
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
/// Insert a point into kd-tree
|
||||
/// @note external point-buffer is used to reduce kd-tree's memory footprint
|
||||
/// @param iPoint index of point in external point-buffer
|
||||
/// @param points external point-buffer
|
||||
void
|
||||
insert(const point_index& iPoint, const std::vector<point_type>& points)
|
||||
{
|
||||
++m_size;
|
||||
// if point is outside root, extend tree by adding new roots
|
||||
const point_type& pos = points[iPoint];
|
||||
while(!isInsideBox(pos, m_min, m_max))
|
||||
{
|
||||
extendTree(pos);
|
||||
}
|
||||
// now insert the point into the tree
|
||||
node_index node = m_root;
|
||||
point_type min = m_min;
|
||||
point_type max = m_max;
|
||||
NodeSplitDirection::Enum dir = m_rootDir;
|
||||
|
||||
// below: initialized only to suppress warnings
|
||||
NodeSplitDirection::Enum newDir(NodeSplitDirection::X);
|
||||
coord_type mid(0);
|
||||
point_type newMin, newMax;
|
||||
while(true)
|
||||
{
|
||||
if(m_nodes[node].isLeaf())
|
||||
{
|
||||
// add point if capacity is not reached
|
||||
point_data_vec& pd = m_nodes[node].data;
|
||||
if(pd.size() < NumVerticesInLeaf)
|
||||
{
|
||||
pd.push_back(iPoint);
|
||||
return;
|
||||
}
|
||||
// initialize bbox first time the root capacity is reached
|
||||
if(!m_isRootBoxInitialized)
|
||||
{
|
||||
initializeRootBox(points);
|
||||
min = m_min;
|
||||
max = m_max;
|
||||
}
|
||||
// split a full leaf node
|
||||
calcSplitInfo(min, max, dir, mid, newDir, newMin, newMax);
|
||||
const node_index c1 = addNewNode(), c2 = addNewNode();
|
||||
Node& n = m_nodes[node];
|
||||
n.setChildren(c1, c2);
|
||||
point_data_vec& c1data = m_nodes[c1].data;
|
||||
point_data_vec& c2data = m_nodes[c2].data;
|
||||
// move node's points to children
|
||||
for(pd_cit it = n.data.begin(); it != n.data.end(); ++it)
|
||||
{
|
||||
whichChild(points[*it], mid, dir) == 0
|
||||
? c1data.push_back(*it)
|
||||
: c2data.push_back(*it);
|
||||
}
|
||||
n.data = point_data_vec();
|
||||
}
|
||||
else
|
||||
{
|
||||
calcSplitInfo(min, max, dir, mid, newDir, newMin, newMax);
|
||||
}
|
||||
// add the point to a child
|
||||
const std::size_t iChild = whichChild(points[iPoint], mid, dir);
|
||||
iChild == 0 ? max = newMax : min = newMin;
|
||||
node = m_nodes[node].children[iChild];
|
||||
dir = newDir;
|
||||
}
|
||||
}
|
||||
|
||||
/// Query kd-tree for a nearest neighbor point
|
||||
/// @note external point-buffer is used to reduce kd-tree's memory footprint
|
||||
/// @param point query point position
|
||||
/// @param points external point-buffer
|
||||
value_type nearest(
|
||||
const point_type& point,
|
||||
const std::vector<point_type>& points) const
|
||||
{
|
||||
value_type out;
|
||||
int iTask = -1;
|
||||
coord_type minDistSq = std::numeric_limits<coord_type>::max();
|
||||
m_tasksStack[++iTask] = NearestTask(
|
||||
m_root,
|
||||
m_min,
|
||||
m_max,
|
||||
m_rootDir,
|
||||
distanceSquaredToBox(point, m_min, m_max));
|
||||
while(iTask != -1)
|
||||
{
|
||||
const NearestTask t = m_tasksStack[iTask--];
|
||||
if(t.distSq > minDistSq)
|
||||
continue;
|
||||
const Node& n = m_nodes[t.node];
|
||||
if(n.isLeaf())
|
||||
{
|
||||
for(pd_cit it = n.data.begin(); it != n.data.end(); ++it)
|
||||
{
|
||||
const point_type& p = points[*it];
|
||||
const coord_type distSq = CDT::distanceSquared(point, p);
|
||||
if(distSq < minDistSq)
|
||||
{
|
||||
minDistSq = distSq;
|
||||
out.first = p;
|
||||
out.second = *it;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
coord_type mid(0);
|
||||
NodeSplitDirection::Enum newDir(NodeSplitDirection::X);
|
||||
point_type newMin = t.min, newMax = t.max;
|
||||
coord_type dSqFarther = std::numeric_limits<coord_type>::max();
|
||||
switch(t.dir)
|
||||
{
|
||||
case NodeSplitDirection::X:
|
||||
{
|
||||
mid = (t.min.x + t.max.x) / coord_type(2);
|
||||
newDir = NodeSplitDirection::Y;
|
||||
newMin.x = mid;
|
||||
newMax.x = mid;
|
||||
const coord_type dx = point.x - mid;
|
||||
const coord_type dy = std::max(
|
||||
std::max(t.min.y - point.y, coord_type(0)),
|
||||
point.y - t.max.y);
|
||||
dSqFarther = dx * dx + dy * dy;
|
||||
break;
|
||||
}
|
||||
case NodeSplitDirection::Y:
|
||||
{
|
||||
mid = (t.min.y + t.max.y) / coord_type(2);
|
||||
newDir = NodeSplitDirection::X;
|
||||
newMin.y = mid;
|
||||
newMax.y = mid;
|
||||
const coord_type dx = std::max(
|
||||
std::max(t.min.x - point.x, coord_type(0)),
|
||||
point.x - t.max.x);
|
||||
const coord_type dy = point.y - mid;
|
||||
dSqFarther = dx * dx + dy * dy;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(iTask + 2 >= static_cast<int>(m_tasksStack.size()))
|
||||
{
|
||||
m_tasksStack.resize(
|
||||
m_tasksStack.size() + StackDepthIncrement);
|
||||
}
|
||||
|
||||
// put the closest node on top of the stack
|
||||
if(isAfterSplit(point, mid, t.dir))
|
||||
{
|
||||
if(dSqFarther <= minDistSq)
|
||||
{
|
||||
m_tasksStack[++iTask] = NearestTask(
|
||||
n.children[0], t.min, newMax, newDir, dSqFarther);
|
||||
}
|
||||
m_tasksStack[++iTask] = NearestTask(
|
||||
n.children[1], newMin, t.max, newDir, t.distSq);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(dSqFarther <= minDistSq)
|
||||
{
|
||||
m_tasksStack[++iTask] = NearestTask(
|
||||
n.children[1], newMin, t.max, newDir, dSqFarther);
|
||||
}
|
||||
m_tasksStack[++iTask] = NearestTask(
|
||||
n.children[0], t.min, newMax, newDir, t.distSq);
|
||||
}
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
private:
|
||||
/// Add a new node and return it's index in nodes buffer
|
||||
node_index addNewNode()
|
||||
{
|
||||
const node_index newNodeIndex = static_cast<node_index>(m_nodes.size());
|
||||
m_nodes.push_back(Node());
|
||||
return newNodeIndex;
|
||||
}
|
||||
|
||||
static bool isAfterSplit(
|
||||
const point_type& point,
|
||||
const coord_type& split,
|
||||
const NodeSplitDirection::Enum dir)
|
||||
{
|
||||
return dir == NodeSplitDirection::X ? point.x > split : point.y > split;
|
||||
}
|
||||
|
||||
/// Test which child point belongs to after the split
|
||||
/// @returns 0 if first child, 1 if second child
|
||||
static std::size_t whichChild(
|
||||
const point_type& point,
|
||||
const coord_type& split,
|
||||
const NodeSplitDirection::Enum dir)
|
||||
{
|
||||
return isAfterSplit(point, split, dir);
|
||||
}
|
||||
|
||||
/// Calculate split location, direction, and children boxes
|
||||
static void calcSplitInfo(
|
||||
const point_type& min,
|
||||
const point_type& max,
|
||||
const NodeSplitDirection::Enum dir,
|
||||
coord_type& midOut,
|
||||
NodeSplitDirection::Enum& newDirOut,
|
||||
point_type& newMinOut,
|
||||
point_type& newMaxOut)
|
||||
{
|
||||
newMaxOut = max;
|
||||
newMinOut = min;
|
||||
switch(dir)
|
||||
{
|
||||
case NodeSplitDirection::X:
|
||||
midOut = (min.x + max.x) / coord_type(2);
|
||||
newDirOut = NodeSplitDirection::Y;
|
||||
newMinOut.x = midOut;
|
||||
newMaxOut.x = midOut;
|
||||
return;
|
||||
case NodeSplitDirection::Y:
|
||||
midOut = (min.y + max.y) / coord_type(2);
|
||||
newDirOut = NodeSplitDirection::X;
|
||||
newMinOut.y = midOut;
|
||||
newMaxOut.y = midOut;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/// Test if point is inside a box
|
||||
static bool isInsideBox(
|
||||
const point_type& p,
|
||||
const point_type& min,
|
||||
const point_type& max)
|
||||
{
|
||||
return p.x >= min.x && p.x <= max.x && p.y >= min.y && p.y <= max.y;
|
||||
}
|
||||
|
||||
/// Extend a tree by creating new root with old root and a new node as
|
||||
/// children
|
||||
void extendTree(const point_type& point)
|
||||
{
|
||||
const node_index newRoot = addNewNode();
|
||||
const node_index newLeaf = addNewNode();
|
||||
switch(m_rootDir)
|
||||
{
|
||||
case NodeSplitDirection::X:
|
||||
m_rootDir = NodeSplitDirection::Y;
|
||||
if(point.y < m_min.y)
|
||||
{
|
||||
m_min.y -= m_max.y - m_min.y;
|
||||
m_nodes[newRoot].setChildren(newLeaf, m_root);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_max.y += m_max.y - m_min.y;
|
||||
m_nodes[newRoot].setChildren(m_root, newLeaf);
|
||||
}
|
||||
break;
|
||||
case NodeSplitDirection::Y:
|
||||
m_rootDir = NodeSplitDirection::X;
|
||||
if(point.x < m_min.x)
|
||||
{
|
||||
m_min.x -= m_max.x - m_min.x;
|
||||
m_nodes[newRoot].setChildren(newLeaf, m_root);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_max.x += m_max.x - m_min.x;
|
||||
m_nodes[newRoot].setChildren(m_root, newLeaf);
|
||||
}
|
||||
break;
|
||||
}
|
||||
m_root = newRoot;
|
||||
}
|
||||
|
||||
/// Calculate root's box enclosing all root points
|
||||
void initializeRootBox(const std::vector<point_type>& points)
|
||||
{
|
||||
const point_data_vec& data = m_nodes[m_root].data;
|
||||
m_min = points[data.front()];
|
||||
m_max = m_min;
|
||||
for(pd_cit it = data.begin(); it != data.end(); ++it)
|
||||
{
|
||||
const point_type& p = points[*it];
|
||||
m_min = point_type(std::min(m_min.x, p.x), std::min(m_min.y, p.y));
|
||||
m_max = point_type(std::max(m_max.x, p.x), std::max(m_max.y, p.y));
|
||||
}
|
||||
// Make sure bounding box does not have a zero size by adding padding:
|
||||
// zero-size bounding box cannot be extended properly
|
||||
const TCoordType padding(1);
|
||||
if(m_min.x == m_max.x)
|
||||
{
|
||||
m_min.x -= padding;
|
||||
m_max.x += padding;
|
||||
}
|
||||
if(m_min.y == m_max.y)
|
||||
{
|
||||
m_min.y -= padding;
|
||||
m_max.y += padding;
|
||||
}
|
||||
m_isRootBoxInitialized = true;
|
||||
}
|
||||
|
||||
static coord_type distanceSquaredToBox(
|
||||
const point_type& p,
|
||||
const point_type& min,
|
||||
const point_type& max)
|
||||
{
|
||||
const coord_type dx =
|
||||
std::max(std::max(min.x - p.x, coord_type(0)), p.x - max.x);
|
||||
const coord_type dy =
|
||||
std::max(std::max(min.y - p.y, coord_type(0)), p.y - max.y);
|
||||
return dx * dx + dy * dy;
|
||||
}
|
||||
|
||||
private:
|
||||
node_index m_root;
|
||||
std::vector<Node> m_nodes;
|
||||
NodeSplitDirection::Enum m_rootDir;
|
||||
point_type m_min;
|
||||
point_type m_max;
|
||||
CDT::VertInd m_size;
|
||||
|
||||
bool m_isRootBoxInitialized;
|
||||
|
||||
// used for nearest query
|
||||
struct NearestTask
|
||||
{
|
||||
node_index node;
|
||||
point_type min, max;
|
||||
NodeSplitDirection::Enum dir;
|
||||
coord_type distSq;
|
||||
NearestTask()
|
||||
: dir(NodeSplitDirection::X)
|
||||
{}
|
||||
NearestTask(
|
||||
const node_index node,
|
||||
const point_type& min,
|
||||
const point_type& max,
|
||||
const NodeSplitDirection::Enum dir,
|
||||
const coord_type distSq = std::numeric_limits<coord_type>::max())
|
||||
: node(node)
|
||||
, min(min)
|
||||
, max(max)
|
||||
, dir(dir)
|
||||
, distSq(distSq)
|
||||
{}
|
||||
};
|
||||
// allocated in class (not in the 'nearest' method) for better performance
|
||||
mutable std::vector<NearestTask> m_tasksStack;
|
||||
};
|
||||
|
||||
} // namespace KDTree
|
||||
} // namespace CDT
|
||||
|
||||
#endif // header guard
|
||||
81
include/CDT/include/LocatorKDTree.h
Normal file
81
include/CDT/include/LocatorKDTree.h
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
/* 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
|
||||
* Adapter between for KDTree and CDT
|
||||
*/
|
||||
|
||||
#ifndef CDT_POINTKDTREE_H
|
||||
#define CDT_POINTKDTREE_H
|
||||
|
||||
#include "CDTUtils.h"
|
||||
#include "KDTree.h"
|
||||
|
||||
namespace CDT
|
||||
{
|
||||
|
||||
/// KD-tree holding points
|
||||
template <
|
||||
typename TCoordType,
|
||||
size_t NumVerticesInLeaf = 32,
|
||||
size_t InitialStackDepth = 32,
|
||||
size_t StackDepthIncrement = 32>
|
||||
class LocatorKDTree
|
||||
{
|
||||
public:
|
||||
/// Initialize KD-tree with points
|
||||
void initialize(const std::vector<V2d<TCoordType> >& points)
|
||||
{
|
||||
typedef V2d<TCoordType> V2d_t;
|
||||
V2d_t min = points.front();
|
||||
V2d_t max = min;
|
||||
typedef typename std::vector<V2d_t>::const_iterator Cit;
|
||||
for(Cit it = points.begin(); it != points.end(); ++it)
|
||||
{
|
||||
min = V2d_t(std::min(min.x, it->x), std::min(min.y, it->y));
|
||||
max = V2d_t(std::max(max.x, it->x), std::max(max.y, it->y));
|
||||
}
|
||||
m_kdTree = KDTree_t(min, max);
|
||||
for(VertInd i(0); i < points.size(); ++i)
|
||||
{
|
||||
m_kdTree.insert(i, points);
|
||||
}
|
||||
}
|
||||
/// Add point to KD-tree
|
||||
void addPoint(const VertInd i, const std::vector<V2d<TCoordType> >& points)
|
||||
{
|
||||
m_kdTree.insert(i, points);
|
||||
}
|
||||
/// Find nearest point using R-tree
|
||||
VertInd nearPoint(
|
||||
const V2d<TCoordType>& pos,
|
||||
const std::vector<V2d<TCoordType> >& points) const
|
||||
{
|
||||
return m_kdTree.nearest(pos, points).second;
|
||||
}
|
||||
|
||||
CDT::VertInd size() const
|
||||
{
|
||||
return m_kdTree.size();
|
||||
}
|
||||
|
||||
bool empty() const
|
||||
{
|
||||
return !size();
|
||||
}
|
||||
|
||||
private:
|
||||
typedef KDTree::KDTree<
|
||||
TCoordType,
|
||||
NumVerticesInLeaf,
|
||||
InitialStackDepth,
|
||||
StackDepthIncrement>
|
||||
KDTree_t;
|
||||
KDTree_t m_kdTree;
|
||||
};
|
||||
|
||||
} // namespace CDT
|
||||
|
||||
#endif
|
||||
1160
include/CDT/include/Triangulation.h
Normal file
1160
include/CDT/include/Triangulation.h
Normal file
File diff suppressed because it is too large
Load diff
2178
include/CDT/include/Triangulation.hpp
Normal file
2178
include/CDT/include/Triangulation.hpp
Normal file
File diff suppressed because it is too large
Load diff
313
include/CDT/include/portable_nth_element.hpp
Normal file
313
include/CDT/include/portable_nth_element.hpp
Normal file
|
|
@ -0,0 +1,313 @@
|
|||
// This code is copied from LLVM's libc++
|
||||
// https://github.com/llvm-mirror/libcxx/blob/4dde9ccef57d50e50620408a0b7a902f0aba803e/include/algorithm
|
||||
// It is needed to provide portable nth_element on different platforms
|
||||
|
||||
// -*- C++ -*-
|
||||
//===-------------------------- algorithm ---------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef CDT_PORTABLE_NTH_ELEMENT
|
||||
#define CDT_PORTABLE_NTH_ELEMENT
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#ifdef CDT_CXX11_IS_SUPPORTED
|
||||
#include <type_traits>
|
||||
#else
|
||||
#include <boost/type_traits/add_lvalue_reference.hpp>
|
||||
#endif
|
||||
|
||||
namespace CDT
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
// sort
|
||||
|
||||
// stable, 2-3 compares, 0-2 swaps
|
||||
|
||||
template <class Compare, class ForwardIterator>
|
||||
unsigned
|
||||
sort3(ForwardIterator x, ForwardIterator y, ForwardIterator z, Compare c)
|
||||
{
|
||||
unsigned r = 0;
|
||||
if(!c(*y, *x)) // if x <= y
|
||||
{
|
||||
if(!c(*z, *y)) // if y <= z
|
||||
return r; // x <= y && y <= z
|
||||
// x <= y && y > z
|
||||
std::swap(*y, *z); // x <= z && y < z
|
||||
r = 1;
|
||||
if(c(*y, *x)) // if x > y
|
||||
{
|
||||
std::swap(*x, *y); // x < y && y <= z
|
||||
r = 2;
|
||||
}
|
||||
return r; // x <= y && y < z
|
||||
}
|
||||
if(c(*z, *y)) // x > y, if y > z
|
||||
{
|
||||
std::swap(*x, *z); // x < y && y < z
|
||||
r = 1;
|
||||
return r;
|
||||
}
|
||||
std::swap(*x, *y); // x > y && y <= z
|
||||
r = 1; // x < y && x <= z
|
||||
if(c(*z, *y)) // if y > z
|
||||
{
|
||||
std::swap(*y, *z); // x <= y && y < z
|
||||
r = 2;
|
||||
}
|
||||
return r;
|
||||
} // x <= y && y <= z
|
||||
|
||||
// Assumes size > 0
|
||||
template <class Compare, class BirdirectionalIterator>
|
||||
void selection_sort(
|
||||
BirdirectionalIterator first,
|
||||
BirdirectionalIterator last,
|
||||
Compare comp)
|
||||
{
|
||||
BirdirectionalIterator lm1 = last;
|
||||
for(--lm1; first != lm1; ++first)
|
||||
{
|
||||
#ifdef CDT_CXX11_IS_SUPPORTED
|
||||
BirdirectionalIterator i = std::min_element<
|
||||
BirdirectionalIterator,
|
||||
typename std::add_lvalue_reference<Compare>::type>(
|
||||
first, last, comp);
|
||||
#else
|
||||
BirdirectionalIterator i = std::min_element<
|
||||
BirdirectionalIterator,
|
||||
typename boost::add_lvalue_reference<Compare>::type>(
|
||||
first, last, comp);
|
||||
#endif
|
||||
if(i != first)
|
||||
std::swap(*first, *i);
|
||||
}
|
||||
}
|
||||
|
||||
// nth_element
|
||||
|
||||
template <class Compare, class RandomAccessIterator>
|
||||
void nth_element(
|
||||
RandomAccessIterator first,
|
||||
RandomAccessIterator nth,
|
||||
RandomAccessIterator last,
|
||||
Compare comp)
|
||||
{
|
||||
// Compare is known to be a reference type
|
||||
typedef typename std::iterator_traits<RandomAccessIterator>::difference_type
|
||||
difference_type;
|
||||
const difference_type limit = 7;
|
||||
while(true)
|
||||
{
|
||||
restart:
|
||||
if(nth == last)
|
||||
return;
|
||||
difference_type len = last - first;
|
||||
switch(len)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
return;
|
||||
case 2:
|
||||
if(comp(*--last, *first))
|
||||
std::swap(*first, *last);
|
||||
return;
|
||||
case 3: {
|
||||
RandomAccessIterator m = first;
|
||||
detail::sort3<Compare>(first, ++m, --last, comp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(len <= limit)
|
||||
{
|
||||
detail::selection_sort<Compare>(first, last, comp);
|
||||
return;
|
||||
}
|
||||
// len > limit >= 3
|
||||
RandomAccessIterator m = first + len / 2;
|
||||
RandomAccessIterator lm1 = last;
|
||||
unsigned n_swaps = detail::sort3<Compare>(first, m, --lm1, comp);
|
||||
// *m is median
|
||||
// partition [first, m) < *m and *m <= [m, last)
|
||||
// (this inhibits tossing elements equivalent to m around
|
||||
// unnecessarily)
|
||||
RandomAccessIterator i = first;
|
||||
RandomAccessIterator j = lm1;
|
||||
// j points beyond range to be tested, *lm1 is known to be <= *m
|
||||
// The search going up is known to be guarded but the search coming
|
||||
// down isn't. Prime the downward search with a guard.
|
||||
if(!comp(*i, *m)) // if *first == *m
|
||||
{
|
||||
// *first == *m, *first doesn't go in first part
|
||||
// manually guard downward moving j against i
|
||||
while(true)
|
||||
{
|
||||
if(i == --j)
|
||||
{
|
||||
// *first == *m, *m <= all other elements
|
||||
// Parition instead into [first, i) == *first and
|
||||
// *first < [i, last)
|
||||
++i; // first + 1
|
||||
j = last;
|
||||
if(!comp(*first, *--j)) // we need a guard if
|
||||
// *first == *(last-1)
|
||||
{
|
||||
while(true)
|
||||
{
|
||||
if(i == j)
|
||||
return; // [first, last) all equivalent
|
||||
// elements
|
||||
if(comp(*first, *i))
|
||||
{
|
||||
std::swap(*i, *j);
|
||||
++n_swaps;
|
||||
++i;
|
||||
break;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
}
|
||||
// [first, i) == *first and *first < [j,
|
||||
// last) and j == last - 1
|
||||
if(i == j)
|
||||
return;
|
||||
while(true)
|
||||
{
|
||||
while(!comp(*first, *i))
|
||||
++i;
|
||||
while(comp(*first, *--j))
|
||||
;
|
||||
if(i >= j)
|
||||
break;
|
||||
std::swap(*i, *j);
|
||||
++n_swaps;
|
||||
++i;
|
||||
}
|
||||
// [first, i) == *first and *first < [i,
|
||||
// last) The first part is sorted,
|
||||
if(nth < i)
|
||||
return;
|
||||
// nth_element the secod part
|
||||
// nth_element<Compare>(i, nth, last, comp);
|
||||
first = i;
|
||||
goto restart;
|
||||
}
|
||||
if(comp(*j, *m))
|
||||
{
|
||||
std::swap(*i, *j);
|
||||
++n_swaps;
|
||||
break; // found guard for downward moving j, now use
|
||||
// unguarded partition
|
||||
}
|
||||
}
|
||||
}
|
||||
++i;
|
||||
// j points beyond range to be tested, *lm1 is known to be <= *m
|
||||
// if not yet partitioned...
|
||||
if(i < j)
|
||||
{
|
||||
// known that *(i - 1) < *m
|
||||
while(true)
|
||||
{
|
||||
// m still guards upward moving i
|
||||
while(comp(*i, *m))
|
||||
++i;
|
||||
// It is now known that a guard exists for downward moving
|
||||
// j
|
||||
while(!comp(*--j, *m))
|
||||
;
|
||||
if(i >= j)
|
||||
break;
|
||||
std::swap(*i, *j);
|
||||
++n_swaps;
|
||||
// It is known that m != j
|
||||
// If m just moved, follow it
|
||||
if(m == i)
|
||||
m = j;
|
||||
++i;
|
||||
}
|
||||
}
|
||||
// [first, i) < *m and *m <= [i, last)
|
||||
if(i != m && comp(*m, *i))
|
||||
{
|
||||
std::swap(*i, *m);
|
||||
++n_swaps;
|
||||
}
|
||||
// [first, i) < *i and *i <= [i+1, last)
|
||||
if(nth == i)
|
||||
return;
|
||||
if(n_swaps == 0)
|
||||
{
|
||||
// We were given a perfectly partitioned sequence. Coincidence?
|
||||
if(nth < i)
|
||||
{
|
||||
// Check for [first, i) already sorted
|
||||
j = m = first;
|
||||
while(++j != i)
|
||||
{
|
||||
if(comp(*j, *m))
|
||||
// not yet sorted, so sort
|
||||
goto not_sorted;
|
||||
m = j;
|
||||
}
|
||||
// [first, i) sorted
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check for [i, last) already sorted
|
||||
j = m = i;
|
||||
while(++j != last)
|
||||
{
|
||||
if(comp(*j, *m))
|
||||
// not yet sorted, so sort
|
||||
goto not_sorted;
|
||||
m = j;
|
||||
}
|
||||
// [i, last) sorted
|
||||
return;
|
||||
}
|
||||
}
|
||||
not_sorted:
|
||||
// nth_element on range containing nth
|
||||
if(nth < i)
|
||||
{
|
||||
// nth_element<Compare>(first, nth, i, comp);
|
||||
last = i;
|
||||
}
|
||||
else
|
||||
{
|
||||
// nth_element<Compare>(i+1, nth, last, comp);
|
||||
first = ++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class _RandomAccessIterator, class _Compare>
|
||||
inline void portable_nth_element(
|
||||
_RandomAccessIterator first,
|
||||
_RandomAccessIterator nth,
|
||||
_RandomAccessIterator last,
|
||||
_Compare comp)
|
||||
{
|
||||
#ifdef CDT_CXX11_IS_SUPPORTED
|
||||
detail::nth_element<typename std::add_lvalue_reference<_Compare>::type>(
|
||||
first, nth, last, comp);
|
||||
#else
|
||||
detail::nth_element<typename boost::add_lvalue_reference<_Compare>::type>(
|
||||
first, nth, last, comp);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace CDT
|
||||
|
||||
#endif // CDT_PORTABLE_NTH_ELEMENT
|
||||
915
include/CDT/include/predicates.h
Normal file
915
include/CDT/include/predicates.h
Normal file
|
|
@ -0,0 +1,915 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (c) 2019, William C. Lenthe *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* Redistribution and use in source and binary forms, with or without *
|
||||
* modification, are permitted provided that the following conditions are met: *
|
||||
* *
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this *
|
||||
* list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, *
|
||||
* this list of conditions and the following disclaimer in the documentation *
|
||||
* and/or other materials provided with the distribution. *
|
||||
* *
|
||||
* 3. Neither the name of the copyright holder nor the names of its *
|
||||
* contributors may be used to endorse or promote products derived from *
|
||||
* this software without specific prior written permission. *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" *
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE *
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE *
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL *
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR *
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER *
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, *
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE *
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
|
||||
* *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef PREDICATES_H_INCLUDED
|
||||
#define PREDICATES_H_INCLUDED
|
||||
|
||||
//@reference: https://www.cs.cmu.edu/~quake/robust.html
|
||||
|
||||
namespace predicates {
|
||||
//@brief: geometric predicates using arbitrary precision arithmetic
|
||||
//@note : these are provided primarily for illustrative purposes and adaptive routines should be preferred
|
||||
namespace exact {
|
||||
//@brief : determine if the 2d point c is above, on, or below the line defined by a and b
|
||||
//@param ax: X-coordinate of a
|
||||
//@param ay: Y-coordinate of a
|
||||
//@param bx: X-coordinate of b
|
||||
//@param by: Y-coordinate of b
|
||||
//@param cx: X-coordinate of c
|
||||
//@param cy: Y-coordinate of c
|
||||
//@return : determinant of {{ax - cx, ay - cy}, {bx - cx, by - cy}}
|
||||
//@note : positive, 0, negative result for c above, on, or below the line defined by a -> b
|
||||
template <typename T> T orient2d(T const ax, T const ay, T const bx, T const by, T const cx, T const cy);
|
||||
|
||||
//@brief : determine if the 2d point c is above, on, or below the line defined by a and b
|
||||
//@param pa: pointer to a as {x, y}
|
||||
//@param pb: pointer to b as {x, y}
|
||||
//@param pc: pointer to c as {x, y}
|
||||
//@return : determinant of {{ax - cx, ay - cy}, {bx - cx, by - cy}}
|
||||
//@note : positive, 0, negative result for c above, on, or below the line defined by a -> b
|
||||
template <typename T> T orient2d(T const*const pa, T const*const pb, T const*const pc);
|
||||
|
||||
//@brief : determine if the 2d point d is inside, on, or outside the circle defined by a, b, and c
|
||||
//@param ax: X-coordinate of a
|
||||
//@param ay: Y-coordinate of a
|
||||
//@param bx: X-coordinate of b
|
||||
//@param by: Y-coordinate of b
|
||||
//@param cx: X-coordinate of c
|
||||
//@param cy: Y-coordinate of c
|
||||
//@param dx: X-coordinate of d
|
||||
//@param dy: Y-coordinate of d
|
||||
//@return : determinant of {{ax - dx, ay - dy, (ax - dx)^2 + (ay - dy)^2}, {bx - dx, by - dy, (bx - dx)^2 + (by - dy)^2}, {cx - dx, cy - dy, (cx - dx)^2 + (cy - dy)^2}}
|
||||
//@note : positive, 0, negative result for d inside, on, or outside the circle defined by a, b, and c
|
||||
template <typename T> T incircle(T const ax, T const ay, T const bx, T const by, T const cx, T const cy, T const dx, T const dy);
|
||||
|
||||
//@brief : determine if the 2d point d is inside, on, or outside the circle defined by a, b, and c
|
||||
//@param pa: pointer to a as {x, y}
|
||||
//@param pb: pointer to b as {x, y}
|
||||
//@param pc: pointer to c as {x, y}
|
||||
//@param pc: pointer to d as {x, y}
|
||||
//@return : determinant of {{ax - dx, ay - dy, (ax - dx)^2 + (ay - dy)^2}, {bx - dx, by - dy, (bx - dx)^2 + (by - dy)^2}, {cx - dx, cy - dy, (cx - dx)^2 + (cy - dy)^2}}
|
||||
//@note : positive, 0, negative result for d inside, on, or outside the circle defined by a, b, and c
|
||||
template <typename T> T incircle(T const*const pa, T const*const pb, T const*const pc, T const*const pd);
|
||||
|
||||
//@brief : determine if the 3d point d is above, on, or below the plane defined by a, b, and c
|
||||
//@param pa: pointer to a as {x, y, z}
|
||||
//@param pb: pointer to b as {x, y, z}
|
||||
//@param pc: pointer to c as {x, y, z}
|
||||
//@param pd: pointer to d as {x, y, z}
|
||||
//@return : determinant of {{ax - dx, ay - dy, az - dz}, {bx - dx, by - dy, bz - dz}, {cx - dx, cy - dy, cz - dz}}
|
||||
//@note : positive, 0, negative result for c above, on, or below the plane defined by a, b, and c
|
||||
template <typename T> T orient3d(T const*const pa, T const*const pb, T const*const pc, T const*const pd);
|
||||
|
||||
//@brief : determine if the 3d point e is inside, on, or outside the sphere defined by a, b, c, and d
|
||||
//@param pa: pointer to a as {x, y, z}
|
||||
//@param pb: pointer to b as {x, y, z}
|
||||
//@param pc: pointer to c as {x, y, z}
|
||||
//@param pd: pointer to d as {x, y, z}
|
||||
//@param pe: pointer to e as {x, y, z}
|
||||
//@return : determinant of {{ax - ex, ay - ey, az - ez, (ax - ex)^2 + (ay - ey)^2 + (az - ez)^2}, {bx - ex, by - ey, bz - ez, (bx - ex)^2 + (by - ey)^2 + (bz - ez)^2}, {cx - ex, cy - ey, cz - ez, (cx - ex)^2 + (cy - ey)^2 + (cz - ez)^2}, {dx - ex, dy - ey, dz - ez, (dx - ex)^2 + (dy - ey)^2 + (dz - ez)^2}}
|
||||
//@note : positive, 0, negative result for d inside, on, or outside the circle defined by a, b, and c
|
||||
template <typename T> T insphere(T const*const pa, T const*const pb, T const*const pc, T const*const pd, T const*const pe);
|
||||
}
|
||||
|
||||
//@brief: geometric predicates using normal floating point arithmetic but falling back to arbitrary precision when needed
|
||||
//@note : these should have the same accuracy but are significantly faster when determinants are large
|
||||
namespace adaptive {
|
||||
//@brief : determine if the 2d point c is above, on, or below the line defined by a and b
|
||||
//@param ax: X-coordinate of a
|
||||
//@param ay: Y-coordinate of a
|
||||
//@param bx: X-coordinate of b
|
||||
//@param by: Y-coordinate of b
|
||||
//@param cx: X-coordinate of c
|
||||
//@param cy: Y-coordinate of c
|
||||
//@return : determinant of {{ax - cx, ay - cy}, {bx - cx, by - cy}}
|
||||
//@note : positive, 0, negative result for c above, on, or below the line defined by a -> b
|
||||
template <typename T> T orient2d(T const ax, T const ay, T const bx, T const by, T const cx, T const cy);
|
||||
|
||||
//@brief : determine if the 2d point c is above, on, or below the line defined by a and b
|
||||
//@param pa: pointer to a as {x, y}
|
||||
//@param pb: pointer to b as {x, y}
|
||||
//@param pc: pointer to c as {x, y}
|
||||
//@return : determinant of {{ax - cx, ay - cy}, {bx - cx, by - cy}}
|
||||
//@note : positive, 0, negative result for c above, on, or below the line defined by a -> b
|
||||
template <typename T> T orient2d(T const*const pa, T const*const pb, T const*const pc);
|
||||
|
||||
//@brief : determine if the 2d point d is inside, on, or outside the circle defined by a, b, and c
|
||||
//@param ax: X-coordinate of a
|
||||
//@param ay: Y-coordinate of a
|
||||
//@param bx: X-coordinate of b
|
||||
//@param by: Y-coordinate of b
|
||||
//@param cx: X-coordinate of c
|
||||
//@param cy: Y-coordinate of c
|
||||
//@param dx: X-coordinate of d
|
||||
//@param dy: Y-coordinate of d
|
||||
//@return : determinant of {{ax - dx, ay - dy, (ax - dx)^2 + (ay - dy)^2}, {bx - dx, by - dy, (bx - dx)^2 + (by - dy)^2}, {cx - dx, cy - dy, (cx - dx)^2 + (cy - dy)^2}}
|
||||
//@note : positive, 0, negative result for d inside, on, or outside the circle defined by a, b, and c
|
||||
template <typename T> T incircle(T const ax, T const ay, T const bx, T const by, T const cx, T const cy, T const dx, T const dy);
|
||||
|
||||
//@brief : determine if the 2d point d is inside, on, or outside the circle defined by a, b, and c
|
||||
//@param pa: pointer to a as {x, y}
|
||||
//@param pb: pointer to b as {x, y}
|
||||
//@param pc: pointer to c as {x, y}
|
||||
//@param pc: pointer to d as {x, y}
|
||||
//@return : determinant of {{ax - dx, ay - dy, (ax - dx)^2 + (ay - dy)^2}, {bx - dx, by - dy, (bx - dx)^2 + (by - dy)^2}, {cx - dx, cy - dy, (cx - dx)^2 + (cy - dy)^2}}
|
||||
//@note : positive, 0, negative result for d inside, on, or outside the circle defined by a, b, and c
|
||||
template <typename T> T incircle(T const*const pa, T const*const pb, T const*const pc, T const*const pd);
|
||||
|
||||
//@brief : determine if the 3d point d is above, on, or below the plane defined by a, b, and c
|
||||
//@param pa: pointer to a as {x, y, z}
|
||||
//@param pb: pointer to b as {x, y, z}
|
||||
//@param pc: pointer to c as {x, y, z}
|
||||
//@param pd: pointer to d as {x, y, z}
|
||||
//@return : determinant of {{ax - dx, ay - dy, az - dz}, {bx - dx, by - dy, bz - dz}, {cx - dx, cy - dy, cz - dz}}
|
||||
//@note : positive, 0, negative result for c above, on, or below the plane defined by a, b, and c
|
||||
template <typename T> T orient3d(T const*const pa, T const*const pb, T const*const pc, T const*const pd);
|
||||
|
||||
//@brief : determine if the 3d point e is inside, on, or outside the sphere defined by a, b, c, and d
|
||||
//@param pa: pointer to a as {x, y, z}
|
||||
//@param pb: pointer to b as {x, y, z}
|
||||
//@param pc: pointer to c as {x, y, z}
|
||||
//@param pd: pointer to d as {x, y, z}
|
||||
//@param pe: pointer to e as {x, y, z}
|
||||
//@return : determinant of {{ax - ex, ay - ey, az - ez, (ax - ex)^2 + (ay - ey)^2 + (az - ez)^2}, {bx - ex, by - ey, bz - ez, (bx - ex)^2 + (by - ey)^2 + (bz - ez)^2}, {cx - ex, cy - ey, cz - ez, (cx - ex)^2 + (cy - ey)^2 + (cz - ez)^2}, {dx - ex, dy - ey, dz - ez, (dx - ex)^2 + (dy - ey)^2 + (dz - ez)^2}}
|
||||
//@note : positive, 0, negative result for d inside, on, or outside the circle defined by a, b, and c
|
||||
template <typename T> T insphere(T const*const pa, T const*const pb, T const*const pc, T const*const pd, T const*const pe);
|
||||
}
|
||||
}
|
||||
|
||||
#include <cmath>//abs, fma
|
||||
#include <limits>
|
||||
#include <utility>//pair
|
||||
#include <numeric>//accumulate
|
||||
#include <algorithm>//transform, copy_n, merge
|
||||
#include <functional>//negate
|
||||
|
||||
// a macro based static assert for pre c++11
|
||||
#define PREDICATES_PORTABLE_STATIC_ASSERT(condition, message) typedef char message[(condition) ? 1 : -1]
|
||||
|
||||
// check if c++11 is supported
|
||||
#if !defined(__cplusplus) && !defined(_MSC_VER)
|
||||
PREDICATES_PORTABLE_STATIC_ASSERT(false, couldnt_parse_cxx_standard)
|
||||
#endif
|
||||
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900)
|
||||
#define PREDICATES_CXX11_IS_SUPPORTED
|
||||
#endif
|
||||
|
||||
// choose to use c++11 features or their backports
|
||||
#ifdef PREDICATES_CXX11_IS_SUPPORTED
|
||||
#include <array>
|
||||
#include <type_traits>// is_same, enable_if
|
||||
#undef PREDICATES_PORTABLE_STATIC_ASSERT
|
||||
#define PREDICATES_TOKEN_TO_STRING1(x) #x
|
||||
#define PREDICATES_TOKEN_TO_STRING(x) PREDICATES_TOKEN_TO_STRING1(x)
|
||||
#define PREDICATES_PORTABLE_STATIC_ASSERT(condition, message) static_assert(condition, PREDICATES_TOKEN_TO_STRING(message))
|
||||
namespace predicates {
|
||||
namespace stdx {
|
||||
using std::array;
|
||||
using std::copy_n;
|
||||
}
|
||||
#else
|
||||
namespace predicates {
|
||||
namespace stdx {
|
||||
// array
|
||||
template<typename T, size_t N>
|
||||
class array {
|
||||
T buff[N];
|
||||
public:
|
||||
T& operator[](const size_t& i) { return buff[i]; }
|
||||
const T& operator[](const size_t& i) const { return buff[i]; }
|
||||
|
||||
T * data() { return buff; }
|
||||
T const * data() const { return buff; }
|
||||
|
||||
T * begin() { return buff; }
|
||||
T const * cbegin() const { return buff; }
|
||||
};
|
||||
// copy_n
|
||||
template< class InputIt, class Size, class OutputIt>
|
||||
OutputIt copy_n(InputIt first, Size count, OutputIt result)
|
||||
{
|
||||
if (count > 0) {
|
||||
*result++ = *first;
|
||||
for (Size i = 1; i < count; ++i) {
|
||||
*result++ = *++first;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
#endif // PREDICATES_CXX11_IS_SUPPORTED
|
||||
|
||||
namespace detail {
|
||||
template<typename T> class ExpansionBase;
|
||||
|
||||
//@brief: class to exactly represent the result of a sequence of arithmetic operations as an sequence of values that sum to the result
|
||||
template<typename T, size_t N>
|
||||
class Expansion : private ExpansionBase<T>, public stdx::array<T, N> {
|
||||
private:
|
||||
public:
|
||||
size_t m_size;
|
||||
template <typename S> friend class ExpansionBase;//access for base class
|
||||
template <typename S, size_t M> friend class Expansion;//access for expansions of different size
|
||||
|
||||
Expansion() : m_size(0) {}
|
||||
template <size_t M> Expansion& operator=(const Expansion<T, M>& e) {
|
||||
PREDICATES_PORTABLE_STATIC_ASSERT(M <= N, cannot_assign_a_larger_expansion_to_a_smaller_expansion);
|
||||
stdx::copy_n(e.cbegin(), e.size(), stdx::array<T, N>::begin());
|
||||
m_size = e.size();
|
||||
return *this;
|
||||
}
|
||||
|
||||
//vector like convenience functions
|
||||
size_t size() const {return m_size;}
|
||||
bool empty() const {return 0 == m_size;}
|
||||
void push_back(const T v) {stdx::array<T, N>::operator[](m_size++) = v;}
|
||||
|
||||
public:
|
||||
//estimates of expansion value
|
||||
T mostSignificant() const {return empty() ? T(0) : stdx::array<T, N>::operator[](m_size - 1);}
|
||||
T estimate() const {return std::accumulate(stdx::array<T, N>::cbegin(), stdx::array<T, N>::cbegin() + size(), T(0));}
|
||||
|
||||
template <size_t M> Expansion<T, N+M> operator+(const Expansion<T, M>& f) const {
|
||||
Expansion<T, N+M> h;
|
||||
h.m_size = ExpansionBase<T>::ExpansionSum(this->data(), this->size(), f.data(), f.size(), h.data());
|
||||
return h;
|
||||
}
|
||||
|
||||
void negate() {std::transform(stdx::array<T, N>::cbegin(), stdx::array<T, N>::cbegin() + size(), stdx::array<T, N>::begin(), std::negate<T>());}
|
||||
Expansion operator-() const {Expansion e = *this; e.negate(); return e;}
|
||||
template <size_t M> Expansion<T, N+M> operator-(const Expansion<T, M>& f) const {return operator+(-f);}
|
||||
|
||||
Expansion<T, 2*N> operator*(const T b) const {
|
||||
Expansion<T, 2*N> h;
|
||||
h.m_size = ExpansionBase<T>::ScaleExpansion(this->data(), this->size(), b, h.data());
|
||||
return h;
|
||||
}
|
||||
};
|
||||
|
||||
// See: https://stackoverflow.com/a/40765925/1597714
|
||||
// Standard defines: https://en.cppreference.com/w/cpp/numeric/math/fma
|
||||
#if defined(__FMA__) || defined(__FMA4__) || defined(__AVX2__) || (defined(FP_FAST_FMA) && defined(FP_FAST_FMAF))
|
||||
#define PREDICATES_FAST_FMA 1
|
||||
#endif
|
||||
|
||||
//@brief : helper function to sort by absolute value
|
||||
//@param a: lhs item to compare
|
||||
//@param b: rhs item to compare
|
||||
//@return : true if |a| < |b|
|
||||
//@note : defined since lambda functions aren't allow in c++03
|
||||
template <typename T> bool absLess(const T& a, const T& b) {return std::abs(a) < std::abs(b);}
|
||||
|
||||
template<typename T>
|
||||
class ExpansionBase {
|
||||
private:
|
||||
static const T Splitter;
|
||||
|
||||
PREDICATES_PORTABLE_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, Requires_IEC_559_IEEE_754_floating_point_type);
|
||||
PREDICATES_PORTABLE_STATIC_ASSERT(2 == std::numeric_limits<T>::radix, Requires_base_2_floating_point_type);
|
||||
|
||||
//combine result + roundoff error into expansion
|
||||
static inline Expansion<T, 2> MakeExpansion(const T value, const T tail) {
|
||||
Expansion<T, 2> e;
|
||||
if(T(0) != tail) e.push_back(tail);
|
||||
if(T(0) != value) e.push_back(value);
|
||||
return e;
|
||||
}
|
||||
|
||||
protected:
|
||||
//add 2 expansions
|
||||
static size_t ExpansionSum(T const * const e, const size_t n, T const * const f, const size_t m, T * const h) {
|
||||
std::merge(e, e + n, f, f + m, h, absLess<T>);
|
||||
if(m == 0) return n;
|
||||
if(n == 0) return m;
|
||||
size_t hIndex = 0;
|
||||
T Q = h[0];
|
||||
T Qnew = h[1] + Q;
|
||||
T hh = FastPlusTail(h[1], Q, Qnew);
|
||||
Q = Qnew;
|
||||
if(T(0) != hh) h[hIndex++] = hh;
|
||||
for(size_t g = 2; g != n + m; ++g) {
|
||||
Qnew = Q + h[g];
|
||||
hh = PlusTail(Q, h[g], Qnew);
|
||||
Q = Qnew;
|
||||
if(T(0) != hh) h[hIndex++] = hh;
|
||||
}
|
||||
if(T(0) != Q) h[hIndex++] = Q;
|
||||
return hIndex;
|
||||
}
|
||||
|
||||
//scale an expansion by a constant
|
||||
static size_t ScaleExpansion(T const * const e, const size_t n, const T b, T * const h) {
|
||||
if(n == 0 || T(0) == b) return 0;
|
||||
size_t hIndex = 0;
|
||||
T Q = e[0] * b;
|
||||
const std::pair<T, T> bSplit = Split(b);
|
||||
T hh = MultTailPreSplit(e[0], b, bSplit, Q);
|
||||
if(T(0) != hh) h[hIndex++] = hh;
|
||||
for(size_t eIndex = 1; eIndex < n; ++eIndex) {
|
||||
T Ti = e[eIndex] * b;
|
||||
T ti = MultTailPreSplit(e[eIndex], b, bSplit, Ti);
|
||||
T Qi = Q + ti;
|
||||
hh = PlusTail(Q, ti, Qi);
|
||||
if(T(0) != hh) h[hIndex++] = hh;
|
||||
Q = Ti + Qi;
|
||||
hh = FastPlusTail(Ti, Qi, Q);
|
||||
if(T(0) != hh) h[hIndex++] = hh;
|
||||
}
|
||||
if(T(0) != Q) h[hIndex++] = Q;
|
||||
return hIndex;
|
||||
}
|
||||
|
||||
public:
|
||||
//roundoff error of x = a + b
|
||||
static inline T PlusTail(const T a, const T b, const T x) {
|
||||
const T bVirtual = x - a;
|
||||
const T aVirtual = x - bVirtual;
|
||||
const T bRoundoff = b - bVirtual;
|
||||
const T aRoundoff = a - aVirtual;
|
||||
return aRoundoff + bRoundoff;
|
||||
}
|
||||
|
||||
//roundoff error of x = a + b if |a| > |b|
|
||||
static inline T FastPlusTail(const T a, const T b, const T x) {
|
||||
const T bVirtual = x - a;
|
||||
return b - bVirtual;
|
||||
}
|
||||
|
||||
//roundoff error of x = a - b
|
||||
static inline T MinusTail(const T a, const T b, const T x) {
|
||||
const T bVirtual = a - x;
|
||||
const T aVirtual = x + bVirtual;
|
||||
const T bRoundoff = bVirtual - b;
|
||||
const T aRoundoff = a - aVirtual;
|
||||
return aRoundoff + bRoundoff;
|
||||
}
|
||||
|
||||
//split a into 2 nonoverlapping values
|
||||
static inline std::pair<T, T> Split(const T a) {
|
||||
const T c = a * Splitter;
|
||||
const T aBig = c - a;
|
||||
const T aHi = c - aBig;
|
||||
return std::pair<T, T>(aHi, a - aHi);
|
||||
}
|
||||
|
||||
//roundoff error of x = a * b via dekkers product
|
||||
static inline T DekkersProduct(const T /*a*/, const std::pair<T, T> aSplit, const T /*b*/, const std::pair<T, T> bSplit, const T p) {
|
||||
T y = p - T(aSplit.first * bSplit.first);
|
||||
y -= T(aSplit.second * bSplit.first);
|
||||
y -= T(aSplit.first * bSplit.second);
|
||||
return T(aSplit.second * bSplit.second) - y;
|
||||
}
|
||||
|
||||
//roundoff error of x = a * b
|
||||
#if defined(PREDICATES_CXX11_IS_SUPPORTED) && defined(PREDICATES_FAST_FMA)
|
||||
static T MultTail(const T a, const T b, const T p) {return std::fma(a, b, -p);}
|
||||
static T MultTailPreSplit(const T a, const T b, const std::pair<T, T> /*bSplit*/, const T p) {return std::fma(a, b, -p);}
|
||||
#else
|
||||
static T MultTail(const T a, const T b, const T p) {return DekkersProduct(a, Split(a), b, Split(b), p);}
|
||||
static T MultTailPreSplit(const T a, const T b, const std::pair<T, T> bSplit, const T p) {return DekkersProduct(a, Split(a), b, bSplit, p);}
|
||||
#endif
|
||||
//expand a + b
|
||||
static inline Expansion<T, 2> Plus(const T a, const T b) {
|
||||
const T x = a + b;
|
||||
return MakeExpansion(x, PlusTail(a, b, x));
|
||||
}
|
||||
|
||||
//expand a - b
|
||||
static inline Expansion<T, 2> Minus(const T a, const T b) {return Plus(a, -b);}
|
||||
|
||||
//expand a * b
|
||||
static inline Expansion<T, 2> Mult(const T a, const T b) {
|
||||
const T x = a * b;
|
||||
return MakeExpansion(x, MultTail(a, b, x));
|
||||
}
|
||||
|
||||
//expand the determinant of {{ax, ay}, {bx, by}} (unrolled Mult(ax, by) - Mult(ay, bx))
|
||||
static inline Expansion<T, 4> TwoTwoDiff(const T ax, const T by, const T ay, const T bx) {
|
||||
const T axby1 = ax * by;
|
||||
const T axby0 = MultTail(ax, by, axby1);
|
||||
const T bxay1 = bx * ay;
|
||||
const T bxay0 = MultTail(bx, ay, bxay1);
|
||||
const T _i0 = axby0 - bxay0;
|
||||
const T x0 = MinusTail(axby0, bxay0, _i0);
|
||||
const T _j = axby1 + _i0;
|
||||
const T _0 = PlusTail(axby1, _i0, _j);
|
||||
const T _i1 = _0 - bxay1;
|
||||
const T x1 = MinusTail(_0, bxay1, _i1);
|
||||
const T x3 = _j + _i1;
|
||||
const T x2 = PlusTail(_j, _i1, x3);
|
||||
Expansion<T, 4> e;
|
||||
if(T(0) != x0) e.push_back(x0);
|
||||
if(T(0) != x1) e.push_back(x1);
|
||||
if(T(0) != x2) e.push_back(x2);
|
||||
if(T(0) != x3) e.push_back(x3);
|
||||
return e;
|
||||
}
|
||||
|
||||
//TwoTwoDiff checking for zeros to avoid extra splitting
|
||||
static inline Expansion<T, 4> TwoTwoDiffZeroCheck(const T ax, const T by, const T ay, const T bx) {
|
||||
Expansion<T, 4> e;
|
||||
if(T(0) == ax && T(0) == ay) return e;
|
||||
else if(T(0) == ax) e = Mult(ay, bx);
|
||||
else if(T(0) == ay) e = Mult(ax, by);
|
||||
else e = TwoTwoDiff(ax, by, ay, bx);
|
||||
return e;
|
||||
}
|
||||
|
||||
//(a * b) * c checking for zeros
|
||||
static inline Expansion<T, 4> ThreeProd(const T a, const T b, const T c) {return (T(0) == a || T(0) == b || T(0) == c) ? Expansion<T, 4>() : Mult(a, b) * c;}
|
||||
};
|
||||
|
||||
template <typename T> const T ExpansionBase<T>::Splitter =
|
||||
#ifdef PREDICATES_CXX11_IS_SUPPORTED
|
||||
static_cast<T>(std::exp2(std::numeric_limits<T>::digits/2 + 1));
|
||||
#else
|
||||
static_cast<T>(std::ldexp(T(1), std::numeric_limits<T>::digits/2 + 1));
|
||||
#endif
|
||||
}
|
||||
|
||||
namespace exact {
|
||||
template <typename T> T orient2d(T const ax, T const ay, T const bx, T const by, T const cx, T const cy)
|
||||
{
|
||||
const detail::Expansion<T, 4> aterms = detail::ExpansionBase<T>::TwoTwoDiff(ax, by, ax, cy);
|
||||
const detail::Expansion<T, 4> bterms = detail::ExpansionBase<T>::TwoTwoDiff(bx, cy, bx, ay);
|
||||
const detail::Expansion<T, 4> cterms = detail::ExpansionBase<T>::TwoTwoDiff(cx, ay, cx, by);
|
||||
const detail::Expansion<T, 12> w = aterms + bterms + cterms;
|
||||
return w.mostSignificant();
|
||||
}
|
||||
|
||||
template <typename T> T orient2d(T const*const pa, T const*const pb, T const*const pc) {
|
||||
return orient2d(pa[0], pa[1], pb[0], pb[1], pc[0], pc[1]);
|
||||
}
|
||||
|
||||
template <typename T> T incircle(T const ax, T const ay, T const bx, T const by, T const cx, T const cy, T const dx, T const dy) {
|
||||
const detail::Expansion<T, 4> ab = detail::ExpansionBase<T>::TwoTwoDiff(ax, by, bx, ay);
|
||||
const detail::Expansion<T, 4> bc = detail::ExpansionBase<T>::TwoTwoDiff(bx, cy, cx, by);
|
||||
const detail::Expansion<T, 4> cd = detail::ExpansionBase<T>::TwoTwoDiff(cx, dy, dx, cy);
|
||||
const detail::Expansion<T, 4> da = detail::ExpansionBase<T>::TwoTwoDiff(dx, ay, ax, dy);
|
||||
const detail::Expansion<T, 4> ac = detail::ExpansionBase<T>::TwoTwoDiff(ax, cy, cx, ay);
|
||||
const detail::Expansion<T, 4> bd = detail::ExpansionBase<T>::TwoTwoDiff(bx, dy, dx, by);
|
||||
|
||||
const detail::Expansion<T, 12> abc = ab + bc - ac;
|
||||
const detail::Expansion<T, 12> bcd = bc + cd - bd;
|
||||
const detail::Expansion<T, 12> cda = cd + da + ac;
|
||||
const detail::Expansion<T, 12> dab = da + ab + bd;
|
||||
|
||||
const detail::Expansion<T, 96> adet = bcd * ax * ax + bcd * ay * ay;
|
||||
const detail::Expansion<T, 96> bdet = cda * bx * -bx + cda * by * -by;
|
||||
const detail::Expansion<T, 96> cdet = dab * cx * cx + dab * cy * cy;
|
||||
const detail::Expansion<T, 96> ddet = abc * dx * -dx + abc * dy * -dy;
|
||||
|
||||
const detail::Expansion<T, 384> deter = (adet + bdet) + (cdet + ddet);
|
||||
return deter.mostSignificant();
|
||||
}
|
||||
|
||||
template <typename T> T incircle(T const*const pa, T const*const pb, T const*const pc, T const*const pd) {
|
||||
return incircle(pa[0], pa[1], pb[0], pb[1], pc[0], pc[1], pd[0], pd[1]);
|
||||
}
|
||||
|
||||
//@brief : determine if the 3d point d is above, on, or below the plane defined by a, b, and c
|
||||
//@param pa: pointer to a as {x, y, z}
|
||||
//@param pb: pointer to b as {x, y, z}
|
||||
//@param pc: pointer to c as {x, y, z}
|
||||
//@param pd: pointer to d as {x, y, z}
|
||||
//@return : determinant of {{ax - dx, ay - dy, az - dz}, {bx - dx, by - dy, bz - dz}, {cx - dx, cy - dy, cz - dz}}
|
||||
//@note : positive, 0, negative result for c above, on, or below the plane defined by a, b, and c
|
||||
template <typename T> T orient3d(T const*const pa, T const*const pb, T const*const pc, T const*const pd) {
|
||||
const detail::Expansion<T, 4> ab = detail::ExpansionBase<T>::TwoTwoDiff(pa[0], pb[1], pb[0], pa[1]);
|
||||
const detail::Expansion<T, 4> bc = detail::ExpansionBase<T>::TwoTwoDiff(pb[0], pc[1], pc[0], pb[1]);
|
||||
const detail::Expansion<T, 4> cd = detail::ExpansionBase<T>::TwoTwoDiff(pc[0], pd[1], pd[0], pc[1]);
|
||||
const detail::Expansion<T, 4> da = detail::ExpansionBase<T>::TwoTwoDiff(pd[0], pa[1], pa[0], pd[1]);
|
||||
const detail::Expansion<T, 4> ac = detail::ExpansionBase<T>::TwoTwoDiff(pa[0], pc[1], pc[0], pa[1]);
|
||||
const detail::Expansion<T, 4> bd = detail::ExpansionBase<T>::TwoTwoDiff(pb[0], pd[1], pd[0], pb[1]);
|
||||
|
||||
const detail::Expansion<T, 12> abc = ab + bc - ac;
|
||||
const detail::Expansion<T, 12> bcd = bc + cd - bd;
|
||||
const detail::Expansion<T, 12> cda = cd + da + ac;
|
||||
const detail::Expansion<T, 12> dab = da + ab + bd;
|
||||
|
||||
const detail::Expansion<T, 24> adet = bcd * pa[2];
|
||||
const detail::Expansion<T, 24> bdet = cda * -pb[2];
|
||||
const detail::Expansion<T, 24> cdet = dab * pc[2];
|
||||
const detail::Expansion<T, 24> ddet = abc * -pd[2];
|
||||
|
||||
const detail::Expansion<T, 96> deter = (adet + bdet) + (cdet + ddet);
|
||||
return deter.mostSignificant();
|
||||
}
|
||||
|
||||
//@brief : determine if the 3d point e is inside, on, or outside the sphere defined by a, b, c, and d
|
||||
//@param pa: pointer to a as {x, y, z}
|
||||
//@param pb: pointer to b as {x, y, z}
|
||||
//@param pc: pointer to c as {x, y, z}
|
||||
//@param pd: pointer to d as {x, y, z}
|
||||
//@param pe: pointer to e as {x, y, z}
|
||||
//@return : determinant of {{ax - ex, ay - ey, az - ez, (ax - ex)^2 + (ay - ey)^2 + (az - ez)^2}, {bx - ex, by - ey, bz - ez, (bx - ex)^2 + (by - ey)^2 + (bz - ez)^2}, {cx - ex, cy - ey, cz - ez, (cx - ex)^2 + (cy - ey)^2 + (cz - ez)^2}, {dx - ex, dy - ey, dz - ez, (dx - ex)^2 + (dy - ey)^2 + (dz - ez)^2}}
|
||||
//@note : positive, 0, negative result for d inside, on, or outside the circle defined by a, b, and c
|
||||
template <typename T> T insphere(T const*const pa, T const*const pb, T const*const pc, T const*const pd, T const*const pe) {
|
||||
const detail::Expansion<T, 4> ab = detail::ExpansionBase<T>::TwoTwoDiff(pa[0], pb[1], pb[0], pa[1]);
|
||||
const detail::Expansion<T, 4> bc = detail::ExpansionBase<T>::TwoTwoDiff(pb[0], pc[1], pc[0], pb[1]);
|
||||
const detail::Expansion<T, 4> cd = detail::ExpansionBase<T>::TwoTwoDiff(pc[0], pd[1], pd[0], pc[1]);
|
||||
const detail::Expansion<T, 4> de = detail::ExpansionBase<T>::TwoTwoDiff(pd[0], pe[1], pe[0], pd[1]);
|
||||
const detail::Expansion<T, 4> ea = detail::ExpansionBase<T>::TwoTwoDiff(pe[0], pa[1], pa[0], pe[1]);
|
||||
const detail::Expansion<T, 4> ac = detail::ExpansionBase<T>::TwoTwoDiff(pa[0], pc[1], pc[0], pa[1]);
|
||||
const detail::Expansion<T, 4> bd = detail::ExpansionBase<T>::TwoTwoDiff(pb[0], pd[1], pd[0], pb[1]);
|
||||
const detail::Expansion<T, 4> ce = detail::ExpansionBase<T>::TwoTwoDiff(pc[0], pe[1], pe[0], pc[1]);
|
||||
const detail::Expansion<T, 4> da = detail::ExpansionBase<T>::TwoTwoDiff(pd[0], pa[1], pa[0], pd[1]);
|
||||
const detail::Expansion<T, 4> eb = detail::ExpansionBase<T>::TwoTwoDiff(pe[0], pb[1], pb[0], pe[1]);
|
||||
|
||||
const detail::Expansion<T, 24> abc = bc * pa[2] + ac * -pb[2] + ab * pc[2];
|
||||
const detail::Expansion<T, 24> bcd = cd * pb[2] + bd * -pc[2] + bc * pd[2];
|
||||
const detail::Expansion<T, 24> cde = de * pc[2] + ce * -pd[2] + cd * pe[2];
|
||||
const detail::Expansion<T, 24> dea = ea * pd[2] + da * -pe[2] + de * pa[2];
|
||||
const detail::Expansion<T, 24> eab = ab * pe[2] + eb * -pa[2] + ea * pb[2];
|
||||
const detail::Expansion<T, 24> abd = bd * pa[2] + da * pb[2] + ab * pd[2];
|
||||
const detail::Expansion<T, 24> bce = ce * pb[2] + eb * pc[2] + bc * pe[2];
|
||||
const detail::Expansion<T, 24> cda = da * pc[2] + ac * pd[2] + cd * pa[2];
|
||||
const detail::Expansion<T, 24> deb = eb * pd[2] + bd * pe[2] + de * pb[2];
|
||||
const detail::Expansion<T, 24> eac = ac * pe[2] + ce * pa[2] + ea * pc[2];
|
||||
|
||||
const detail::Expansion<T, 96> bcde = (cde + bce) - (deb + bcd);
|
||||
const detail::Expansion<T, 96> cdea = (dea + cda) - (eac + cde);
|
||||
const detail::Expansion<T, 96> deab = (eab + deb) - (abd + dea);
|
||||
const detail::Expansion<T, 96> eabc = (abc + eac) - (bce + eab);
|
||||
const detail::Expansion<T, 96> abcd = (bcd + abd) - (cda + abc);
|
||||
|
||||
const detail::Expansion<T, 1152> adet = bcde * pa[0] * pa[0] + bcde * pa[1] * pa[1] + bcde * pa[2] * pa[2];
|
||||
const detail::Expansion<T, 1152> bdet = cdea * pb[0] * pb[0] + cdea * pb[1] * pb[1] + cdea * pb[2] * pb[2];
|
||||
const detail::Expansion<T, 1152> cdet = deab * pc[0] * pc[0] + deab * pc[1] * pc[1] + deab * pc[2] * pc[2];
|
||||
const detail::Expansion<T, 1152> ddet = eabc * pd[0] * pd[0] + eabc * pd[1] * pd[1] + eabc * pd[2] * pd[2];
|
||||
const detail::Expansion<T, 1152> edet = abcd * pe[0] * pe[0] + abcd * pe[1] * pe[1] + abcd * pe[2] * pe[2];
|
||||
|
||||
const detail::Expansion<T, 5760> deter = (adet + bdet) + ((cdet + ddet) + edet);
|
||||
return deter.mostSignificant();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const T& Epsilon()
|
||||
{
|
||||
static const T epsilon =
|
||||
#ifdef PREDICATES_CXX11_IS_SUPPORTED
|
||||
static_cast<T>(std::exp2(-std::numeric_limits<T>::digits));
|
||||
#else
|
||||
static_cast<T>(std::ldexp(T(1), -std::numeric_limits<T>::digits));
|
||||
#endif
|
||||
return epsilon;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
class Constants {
|
||||
public:
|
||||
static const T epsilon, resulterrbound;
|
||||
static const T ccwerrboundA, ccwerrboundB, ccwerrboundC;
|
||||
static const T o3derrboundA, o3derrboundB, o3derrboundC;
|
||||
static const T iccerrboundA, iccerrboundB, iccerrboundC;
|
||||
static const T isperrboundA, isperrboundB, isperrboundC;
|
||||
};
|
||||
|
||||
template <typename T> const T Constants<T>::epsilon = Epsilon<T>();
|
||||
template <typename T> const T Constants<T>::resulterrbound = (T( 3) + T( 8) * Epsilon<T>()) * Epsilon<T>();
|
||||
template <typename T> const T Constants<T>::ccwerrboundA = (T( 3) + T( 16) * Epsilon<T>()) * Epsilon<T>();
|
||||
template <typename T> const T Constants<T>::ccwerrboundB = (T( 2) + T( 12) * Epsilon<T>()) * Epsilon<T>();
|
||||
template <typename T> const T Constants<T>::ccwerrboundC = (T( 9) + T( 64) * Epsilon<T>()) * Epsilon<T>() * Epsilon<T>();
|
||||
template <typename T> const T Constants<T>::o3derrboundA = (T( 7) + T( 56) * Epsilon<T>()) * Epsilon<T>();
|
||||
template <typename T> const T Constants<T>::o3derrboundB = (T( 3) + T( 28) * Epsilon<T>()) * Epsilon<T>();
|
||||
template <typename T> const T Constants<T>::o3derrboundC = (T(26) + T( 288) * Epsilon<T>()) * Epsilon<T>() * Epsilon<T>();
|
||||
template <typename T> const T Constants<T>::iccerrboundA = (T(10) + T( 96) * Epsilon<T>()) * Epsilon<T>();
|
||||
template <typename T> const T Constants<T>::iccerrboundB = (T( 4) + T( 48) * Epsilon<T>()) * Epsilon<T>();
|
||||
template <typename T> const T Constants<T>::iccerrboundC = (T(44) + T( 576) * Epsilon<T>()) * Epsilon<T>() * Epsilon<T>();
|
||||
template <typename T> const T Constants<T>::isperrboundA = (T(16) + T( 224) * Epsilon<T>()) * Epsilon<T>();
|
||||
template <typename T> const T Constants<T>::isperrboundB = (T( 5) + T( 72) * Epsilon<T>()) * Epsilon<T>();
|
||||
template <typename T> const T Constants<T>::isperrboundC = (T(71) + T(1408) * Epsilon<T>()) * Epsilon<T>() * Epsilon<T>();
|
||||
|
||||
namespace adaptive {
|
||||
template <typename T> T orient2d(T const ax, T const ay, T const bx, T const by, T const cx, T const cy) {
|
||||
const T acx = ax - cx;
|
||||
const T bcx = bx - cx;
|
||||
const T acy = ay - cy;
|
||||
const T bcy = by - cy;
|
||||
const T detleft = acx * bcy;
|
||||
const T detright = acy * bcx;
|
||||
T det = detleft - detright;
|
||||
if((detleft < 0) != (detright < 0)) return det;
|
||||
if(T(0) == detleft || T(0) == detright) return det;
|
||||
|
||||
const T detsum = std::abs(detleft + detright);
|
||||
T errbound = Constants<T>::ccwerrboundA * detsum;
|
||||
if(std::abs(det) >= std::abs(errbound)) return det;
|
||||
|
||||
const detail::Expansion<T, 4> B = detail::ExpansionBase<T>::TwoTwoDiff(acx, bcy, acy, bcx);
|
||||
det = B.estimate();
|
||||
errbound = Constants<T>::ccwerrboundB * detsum;
|
||||
if(std::abs(det) >= std::abs(errbound)) return det;
|
||||
|
||||
const T acxtail = detail::ExpansionBase<T>::MinusTail(ax, cx, acx);
|
||||
const T bcxtail = detail::ExpansionBase<T>::MinusTail(bx, cx, bcx);
|
||||
const T acytail = detail::ExpansionBase<T>::MinusTail(ay, cy, acy);
|
||||
const T bcytail = detail::ExpansionBase<T>::MinusTail(by, cy, bcy);
|
||||
if(T(0) == acxtail && T(0) == bcxtail && T(0) == acytail && T(0) == bcytail) return det;
|
||||
|
||||
errbound = Constants<T>::ccwerrboundC * detsum + Constants<T>::resulterrbound * std::abs(det);
|
||||
det += (acx * bcytail + bcy * acxtail) - (acy * bcxtail + bcx * acytail);
|
||||
if(std::abs(det) >= std::abs(errbound)) return det;
|
||||
|
||||
const detail::Expansion<T, 16> D = ((B + detail::ExpansionBase<T>::TwoTwoDiff(acxtail, bcy, acytail, bcx)) + detail::ExpansionBase<T>::TwoTwoDiff(acx, bcytail, acy, bcxtail)) + detail::ExpansionBase<T>::TwoTwoDiff(acxtail, bcytail, acytail, bcxtail);
|
||||
return D.mostSignificant();
|
||||
}
|
||||
|
||||
template <typename T> T orient2d(T const*const pa, T const*const pb, T const*const pc) {
|
||||
return orient2d(pa[0], pa[1], pb[0], pb[1], pc[0], pc[1]);
|
||||
}
|
||||
|
||||
template <typename T> T incircle(T const ax, T const ay, T const bx, T const by, T const cx, T const cy, T const dx, T const dy) {
|
||||
const T adx = ax - dx;
|
||||
const T bdx = bx - dx;
|
||||
const T cdx = cx - dx;
|
||||
const T ady = ay - dy;
|
||||
const T bdy = by - dy;
|
||||
const T cdy = cy - dy;
|
||||
const T bdxcdy = bdx * cdy;
|
||||
const T cdxbdy = cdx * bdy;
|
||||
const T cdxady = cdx * ady;
|
||||
const T adxcdy = adx * cdy;
|
||||
const T adxbdy = adx * bdy;
|
||||
const T bdxady = bdx * ady;
|
||||
const T alift = adx * adx + ady * ady;
|
||||
const T blift = bdx * bdx + bdy * bdy;
|
||||
const T clift = cdx * cdx + cdy * cdy;
|
||||
T det = alift * (bdxcdy - cdxbdy) + blift * (cdxady - adxcdy) + clift * (adxbdy - bdxady);
|
||||
const T permanent = (std::abs(bdxcdy) + std::abs(cdxbdy)) * alift
|
||||
+ (std::abs(cdxady) + std::abs(adxcdy)) * blift
|
||||
+ (std::abs(adxbdy) + std::abs(bdxady)) * clift;
|
||||
T errbound = Constants<T>::iccerrboundA * permanent;
|
||||
if(std::abs(det) >= std::abs(errbound)) return det;
|
||||
|
||||
const detail::Expansion<T, 4> bc = detail::ExpansionBase<T>::TwoTwoDiff(bdx, cdy, cdx, bdy);
|
||||
const detail::Expansion<T, 4> ca = detail::ExpansionBase<T>::TwoTwoDiff(cdx, ady, adx, cdy);
|
||||
const detail::Expansion<T, 4> ab = detail::ExpansionBase<T>::TwoTwoDiff(adx, bdy, bdx, ady);
|
||||
const detail::Expansion<T, 32> adet = bc * adx * adx + bc * ady * ady;
|
||||
const detail::Expansion<T, 32> bdet = ca * bdx * bdx + ca * bdy * bdy;
|
||||
const detail::Expansion<T, 32> cdet = ab * cdx * cdx + ab * cdy * cdy;
|
||||
const detail::Expansion<T, 96> fin1 = adet + bdet + cdet;
|
||||
det = fin1.estimate();
|
||||
errbound = Constants<T>::iccerrboundB * permanent;
|
||||
if(std::abs(det) >= std::abs(errbound)) return det;
|
||||
|
||||
const T adxtail = detail::ExpansionBase<T>::MinusTail(ax, dx, adx);
|
||||
const T adytail = detail::ExpansionBase<T>::MinusTail(ay, dy, ady);
|
||||
const T bdxtail = detail::ExpansionBase<T>::MinusTail(bx, dx, bdx);
|
||||
const T bdytail = detail::ExpansionBase<T>::MinusTail(by, dy, bdy);
|
||||
const T cdxtail = detail::ExpansionBase<T>::MinusTail(cx, dx, cdx);
|
||||
const T cdytail = detail::ExpansionBase<T>::MinusTail(cy, dy, cdy);
|
||||
if(T(0) == adxtail && T(0) == bdxtail && T(0) == cdxtail && T(0) == adytail && T(0) == bdytail && T(0) == cdytail) return det;
|
||||
|
||||
errbound = Constants<T>::iccerrboundC * permanent + Constants<T>::resulterrbound * std::abs(det);
|
||||
det += ((adx * adx + ady * ady) * ((bdx * cdytail + cdy * bdxtail) - (bdy * cdxtail + cdx * bdytail))
|
||||
+ (bdx * cdy - bdy * cdx) * (adx * adxtail + ady * adytail) * T(2))
|
||||
+ ((bdx * bdx + bdy * bdy) * ((cdx * adytail + ady * cdxtail) - (cdy * adxtail + adx * cdytail))
|
||||
+ (cdx * ady - cdy * adx) * (bdx * bdxtail + bdy * bdytail) * T(2))
|
||||
+ ((cdx * cdx + cdy * cdy) * ((adx * bdytail + bdy * adxtail) - (ady * bdxtail + bdx * adytail))
|
||||
+ (adx * bdy - ady * bdx) * (cdx * cdxtail + cdy * cdytail) * T(2));
|
||||
if(std::abs(det) >= std::abs(errbound)) return det;
|
||||
return exact::incircle(ax, ay, bx, by, cx, cy, dx, dy);
|
||||
}
|
||||
|
||||
template <typename T> T incircle(T const*const pa, T const*const pb, T const*const pc, T const*const pd) {
|
||||
return incircle(pa[0], pa[1], pb[0], pb[1], pc[0], pc[1], pd[0], pd[1]);
|
||||
}
|
||||
|
||||
//@brief : determine if the 3d point d is above, on, or below the plane defined by a, b, and c
|
||||
//@param pa: pointer to a as {x, y, z}
|
||||
//@param pb: pointer to b as {x, y, z}
|
||||
//@param pc: pointer to c as {x, y, z}
|
||||
//@param pd: pointer to d as {x, y, z}
|
||||
//@return : determinant of {{ax - dx, ay - dy, az - dz}, {bx - dx, by - dy, bz - dz}, {cx - dx, cy - dy, cz - dz}}
|
||||
//@note : positive, 0, negative result for c above, on, or below the plane defined by a, b, and c
|
||||
template <typename T> T orient3d(T const*const pa, T const*const pb, T const*const pc, T const*const pd) {
|
||||
const T adx = pa[0] - pd[0];
|
||||
const T bdx = pb[0] - pd[0];
|
||||
const T cdx = pc[0] - pd[0];
|
||||
const T ady = pa[1] - pd[1];
|
||||
const T bdy = pb[1] - pd[1];
|
||||
const T cdy = pc[1] - pd[1];
|
||||
const T adz = pa[2] - pd[2];
|
||||
const T bdz = pb[2] - pd[2];
|
||||
const T cdz = pc[2] - pd[2];
|
||||
const T bdxcdy = bdx * cdy;
|
||||
const T cdxbdy = cdx * bdy;
|
||||
const T cdxady = cdx * ady;
|
||||
const T adxcdy = adx * cdy;
|
||||
const T adxbdy = adx * bdy;
|
||||
const T bdxady = bdx * ady;
|
||||
T det = adz * (bdxcdy - cdxbdy) + bdz * (cdxady - adxcdy) + cdz * (adxbdy - bdxady);
|
||||
const T permanent = (std::abs(bdxcdy) + std::abs(cdxbdy)) * std::abs(adz) + (std::abs(cdxady) + std::abs(adxcdy)) * std::abs(bdz) + (std::abs(adxbdy) + std::abs(bdxady)) * std::abs(cdz);
|
||||
T errbound = Constants<T>::o3derrboundA * permanent;
|
||||
if(std::abs(det) >= std::abs(errbound)) return det;
|
||||
|
||||
const detail::Expansion<T, 4> bc = detail::ExpansionBase<T>::TwoTwoDiff(bdx, cdy, cdx, bdy);
|
||||
const detail::Expansion<T, 4> ca = detail::ExpansionBase<T>::TwoTwoDiff(cdx, ady, adx, cdy);
|
||||
const detail::Expansion<T, 4> ab = detail::ExpansionBase<T>::TwoTwoDiff(adx, bdy, bdx, ady);
|
||||
const detail::Expansion<T, 24> fin1 = (bc * adz + ca * bdz) + ab * cdz;
|
||||
det = fin1.estimate();
|
||||
errbound = Constants<T>::o3derrboundB * permanent;
|
||||
if(std::abs(det) >= std::abs(errbound)) return det;
|
||||
|
||||
const T adxtail = detail::ExpansionBase<T>::MinusTail(pa[0], pd[0], adx);
|
||||
const T bdxtail = detail::ExpansionBase<T>::MinusTail(pb[0], pd[0], bdx);
|
||||
const T cdxtail = detail::ExpansionBase<T>::MinusTail(pc[0], pd[0], cdx);
|
||||
const T adytail = detail::ExpansionBase<T>::MinusTail(pa[1], pd[1], ady);
|
||||
const T bdytail = detail::ExpansionBase<T>::MinusTail(pb[1], pd[1], bdy);
|
||||
const T cdytail = detail::ExpansionBase<T>::MinusTail(pc[1], pd[1], cdy);
|
||||
const T adztail = detail::ExpansionBase<T>::MinusTail(pa[2], pd[2], adz);
|
||||
const T bdztail = detail::ExpansionBase<T>::MinusTail(pb[2], pd[2], bdz);
|
||||
const T cdztail = detail::ExpansionBase<T>::MinusTail(pc[2], pd[2], cdz);
|
||||
if(T(0) == adxtail && T(0) == adytail && T(0) == adztail &&
|
||||
T(0) == bdxtail && T(0) == bdytail && T(0) == bdztail &&
|
||||
T(0) == cdxtail && T(0) == cdytail && T(0) == cdztail) return det;
|
||||
|
||||
errbound = Constants<T>::o3derrboundC * permanent + Constants<T>::resulterrbound * std::abs(det);
|
||||
det += (adz * ((bdx * cdytail + cdy * bdxtail) - (bdy * cdxtail + cdx * bdytail)) + adztail * (bdx * cdy - bdy * cdx))
|
||||
+ (bdz * ((cdx * adytail + ady * cdxtail) - (cdy * adxtail + adx * cdytail)) + bdztail * (cdx * ady - cdy * adx))
|
||||
+ (cdz * ((adx * bdytail + bdy * adxtail) - (ady * bdxtail + bdx * adytail)) + cdztail * (adx * bdy - ady * bdx));
|
||||
if(std::abs(det) >= std::abs(errbound)) return det;
|
||||
|
||||
const detail::Expansion<T, 8> bct = detail::ExpansionBase<T>::TwoTwoDiffZeroCheck(bdxtail, cdy, bdytail, cdx) + detail::ExpansionBase<T>::TwoTwoDiffZeroCheck(cdytail, bdx, cdxtail, bdy);
|
||||
const detail::Expansion<T, 8> cat = detail::ExpansionBase<T>::TwoTwoDiffZeroCheck(cdxtail, ady, cdytail, adx) + detail::ExpansionBase<T>::TwoTwoDiffZeroCheck(adytail, cdx, adxtail, cdy);
|
||||
const detail::Expansion<T, 8> abt = detail::ExpansionBase<T>::TwoTwoDiffZeroCheck(adxtail, bdy, adytail, bdx) + detail::ExpansionBase<T>::TwoTwoDiffZeroCheck(bdytail, adx, bdxtail, ady);
|
||||
const detail::Expansion<T, 192> fin2 = fin1 + bct * adz + cat * bdz + abt * cdz + bc * adztail + ca * bdztail + ab * cdztail
|
||||
+ detail::ExpansionBase<T>::ThreeProd( adxtail, bdytail, cdz) + detail::ExpansionBase<T>::ThreeProd( adxtail, bdytail, cdztail)
|
||||
+ detail::ExpansionBase<T>::ThreeProd(-adxtail, cdytail, bdz) + detail::ExpansionBase<T>::ThreeProd(-adxtail, cdytail, bdztail)
|
||||
+ detail::ExpansionBase<T>::ThreeProd( bdxtail, cdytail, adz) + detail::ExpansionBase<T>::ThreeProd( bdxtail, cdytail, adztail)
|
||||
+ detail::ExpansionBase<T>::ThreeProd(-bdxtail, adytail, cdz) + detail::ExpansionBase<T>::ThreeProd(-bdxtail, adytail, cdztail)
|
||||
+ detail::ExpansionBase<T>::ThreeProd( cdxtail, adytail, bdz) + detail::ExpansionBase<T>::ThreeProd( cdxtail, adytail, bdztail)
|
||||
+ detail::ExpansionBase<T>::ThreeProd(-cdxtail, bdytail, adz) + detail::ExpansionBase<T>::ThreeProd(-cdxtail, bdytail, adztail)
|
||||
+ bct * adztail + cat * bdztail + abt * cdztail;
|
||||
return fin2.mostSignificant();
|
||||
}
|
||||
|
||||
//@brief : determine if the 3d point e is inside, on, or outside the sphere defined by a, b, c, and d
|
||||
//@param pa: pointer to a as {x, y, z}
|
||||
//@param pb: pointer to b as {x, y, z}
|
||||
//@param pc: pointer to c as {x, y, z}
|
||||
//@param pd: pointer to d as {x, y, z}
|
||||
//@param pe: pointer to e as {x, y, z}
|
||||
//@return : determinant of {{ax - ex, ay - ey, az - ez, (ax - ex)^2 + (ay - ey)^2 + (az - ez)^2}, {bx - ex, by - ey, bz - ez, (bx - ex)^2 + (by - ey)^2 + (bz - ez)^2}, {cx - ex, cy - ey, cz - ez, (cx - ex)^2 + (cy - ey)^2 + (cz - ez)^2}, {dx - ex, dy - ey, dz - ez, (dx - ex)^2 + (dy - ey)^2 + (dz - ez)^2}}
|
||||
//@note : positive, 0, negative result for d inside, on, or outside the circle defined by a, b, and c
|
||||
template <typename T> T insphere(T const*const pa, T const*const pb, T const*const pc, T const*const pd, T const*const pe) {
|
||||
T permanent;
|
||||
const T aex = pa[0] - pe[0];
|
||||
const T bex = pb[0] - pe[0];
|
||||
const T cex = pc[0] - pe[0];
|
||||
const T dex = pd[0] - pe[0];
|
||||
const T aey = pa[1] - pe[1];
|
||||
const T bey = pb[1] - pe[1];
|
||||
const T cey = pc[1] - pe[1];
|
||||
const T dey = pd[1] - pe[1];
|
||||
const T aez = pa[2] - pe[2];
|
||||
const T bez = pb[2] - pe[2];
|
||||
const T cez = pc[2] - pe[2];
|
||||
const T dez = pd[2] - pe[2];
|
||||
{
|
||||
const T aexbey = aex * bey;
|
||||
const T bexaey = bex * aey;
|
||||
const T bexcey = bex * cey;
|
||||
const T cexbey = cex * bey;
|
||||
const T cexdey = cex * dey;
|
||||
const T dexcey = dex * cey;
|
||||
const T dexaey = dex * aey;
|
||||
const T aexdey = aex * dey;
|
||||
const T aexcey = aex * cey;
|
||||
const T cexaey = cex * aey;
|
||||
const T bexdey = bex * dey;
|
||||
const T dexbey = dex * bey;
|
||||
const T ab = aexbey - bexaey;
|
||||
const T bc = bexcey - cexbey;
|
||||
const T cd = cexdey - dexcey;
|
||||
const T da = dexaey - aexdey;
|
||||
const T ac = aexcey - cexaey;
|
||||
const T bd = bexdey - dexbey;
|
||||
const T abc = aez * bc - bez * ac + cez * ab;
|
||||
const T bcd = bez * cd - cez * bd + dez * bc;
|
||||
const T cda = cez * da + dez * ac + aez * cd;
|
||||
const T dab = dez * ab + aez * bd + bez * da;
|
||||
const T alift = aex * aex + aey * aey + aez * aez;
|
||||
const T blift = bex * bex + bey * bey + bez * bez;
|
||||
const T clift = cex * cex + cey * cey + cez * cez;
|
||||
const T dlift = dex * dex + dey * dey + dez * dez;
|
||||
const T det = (dlift * abc - clift * dab) + (blift * cda - alift * bcd);
|
||||
const T aezplus = std::abs(aez);
|
||||
const T bezplus = std::abs(bez);
|
||||
const T cezplus = std::abs(cez);
|
||||
const T dezplus = std::abs(dez);
|
||||
const T aexbeyplus = std::abs(aexbey);
|
||||
const T bexaeyplus = std::abs(bexaey);
|
||||
const T bexceyplus = std::abs(bexcey);
|
||||
const T cexbeyplus = std::abs(cexbey);
|
||||
const T cexdeyplus = std::abs(cexdey);
|
||||
const T dexceyplus = std::abs(dexcey);
|
||||
const T dexaeyplus = std::abs(dexaey);
|
||||
const T aexdeyplus = std::abs(aexdey);
|
||||
const T aexceyplus = std::abs(aexcey);
|
||||
const T cexaeyplus = std::abs(cexaey);
|
||||
const T bexdeyplus = std::abs(bexdey);
|
||||
const T dexbeyplus = std::abs(dexbey);
|
||||
permanent = ((cexdeyplus + dexceyplus) * bezplus + (dexbeyplus + bexdeyplus) * cezplus + (bexceyplus + cexbeyplus) * dezplus) * alift
|
||||
+ ((dexaeyplus + aexdeyplus) * cezplus + (aexceyplus + cexaeyplus) * dezplus + (cexdeyplus + dexceyplus) * aezplus) * blift
|
||||
+ ((aexbeyplus + bexaeyplus) * dezplus + (bexdeyplus + dexbeyplus) * aezplus + (dexaeyplus + aexdeyplus) * bezplus) * clift
|
||||
+ ((bexceyplus + cexbeyplus) * aezplus + (cexaeyplus + aexceyplus) * bezplus + (aexbeyplus + bexaeyplus) * cezplus) * dlift;
|
||||
const T errbound = Constants<T>::isperrboundA * permanent;
|
||||
if(std::abs(det) >= std::abs(errbound)) return det;
|
||||
}
|
||||
|
||||
const detail::Expansion<T, 4> ab = detail::ExpansionBase<T>::TwoTwoDiff(aex, bey, bex, aey);
|
||||
const detail::Expansion<T, 4> bc = detail::ExpansionBase<T>::TwoTwoDiff(bex, cey, cex, bey);
|
||||
const detail::Expansion<T, 4> cd = detail::ExpansionBase<T>::TwoTwoDiff(cex, dey, dex, cey);
|
||||
const detail::Expansion<T, 4> da = detail::ExpansionBase<T>::TwoTwoDiff(dex, aey, aex, dey);
|
||||
const detail::Expansion<T, 4> ac = detail::ExpansionBase<T>::TwoTwoDiff(aex, cey, cex, aey);
|
||||
const detail::Expansion<T, 4> bd = detail::ExpansionBase<T>::TwoTwoDiff(bex, dey, dex, bey);
|
||||
const detail::Expansion<T, 24> temp24a = bc * dez + (cd * bez + bd * -cez);
|
||||
const detail::Expansion<T, 24> temp24b = cd * aez + (da * cez + ac * dez);
|
||||
const detail::Expansion<T, 24> temp24c = da * bez + (ab * dez + bd * aez);
|
||||
const detail::Expansion<T, 24> temp24d = ab * cez + (bc * aez + ac * -bez);
|
||||
const detail::Expansion<T, 288> adet = temp24a * aex * -aex + temp24a * aey * -aey + temp24a * aez * -aez;
|
||||
const detail::Expansion<T, 288> bdet = temp24b * bex * bex + temp24b * bey * bey + temp24b * bez * bez;
|
||||
const detail::Expansion<T, 288> cdet = temp24c * cex * -cex + temp24c * cey * -cey + temp24c * cez * -cez;
|
||||
const detail::Expansion<T, 288> ddet = temp24d * dex * dex + temp24d * dey * dey + temp24d * dez * dez;
|
||||
const detail::Expansion<T, 1152> fin1 = (adet + bdet) + (cdet + ddet);
|
||||
T det = fin1.estimate();
|
||||
T errbound = Constants<T>::isperrboundB * permanent;
|
||||
if(std::abs(det) >= std::abs(errbound)) return det;
|
||||
|
||||
const T aextail = detail::ExpansionBase<T>::MinusTail(pa[0], pe[0], aex);
|
||||
const T aeytail = detail::ExpansionBase<T>::MinusTail(pa[1], pe[1], aey);
|
||||
const T aeztail = detail::ExpansionBase<T>::MinusTail(pa[2], pe[2], aez);
|
||||
const T bextail = detail::ExpansionBase<T>::MinusTail(pb[0], pe[0], bex);
|
||||
const T beytail = detail::ExpansionBase<T>::MinusTail(pb[1], pe[1], bey);
|
||||
const T beztail = detail::ExpansionBase<T>::MinusTail(pb[2], pe[2], bez);
|
||||
const T cextail = detail::ExpansionBase<T>::MinusTail(pc[0], pe[0], cex);
|
||||
const T ceytail = detail::ExpansionBase<T>::MinusTail(pc[1], pe[1], cey);
|
||||
const T ceztail = detail::ExpansionBase<T>::MinusTail(pc[2], pe[2], cez);
|
||||
const T dextail = detail::ExpansionBase<T>::MinusTail(pd[0], pe[0], dex);
|
||||
const T deytail = detail::ExpansionBase<T>::MinusTail(pd[1], pe[1], dey);
|
||||
const T deztail = detail::ExpansionBase<T>::MinusTail(pd[2], pe[2], dez);
|
||||
if (T(0) == aextail && T(0) == aeytail && T(0) == aeztail &&
|
||||
T(0) == bextail && T(0) == beytail && T(0) == beztail &&
|
||||
T(0) == cextail && T(0) == ceytail && T(0) == ceztail &&
|
||||
T(0) == dextail && T(0) == deytail && T(0) == deztail) return det;
|
||||
|
||||
errbound = Constants<T>::isperrboundC * permanent + Constants<T>::resulterrbound * std::abs(det);
|
||||
const T abeps = (aex * beytail + bey * aextail) - (aey * bextail + bex * aeytail);
|
||||
const T bceps = (bex * ceytail + cey * bextail) - (bey * cextail + cex * beytail);
|
||||
const T cdeps = (cex * deytail + dey * cextail) - (cey * dextail + dex * ceytail);
|
||||
const T daeps = (dex * aeytail + aey * dextail) - (dey * aextail + aex * deytail);
|
||||
const T aceps = (aex * ceytail + cey * aextail) - (aey * cextail + cex * aeytail);
|
||||
const T bdeps = (bex * deytail + dey * bextail) - (bey * dextail + dex * beytail);
|
||||
const T ab3 = ab.mostSignificant();
|
||||
const T bc3 = bc.mostSignificant();
|
||||
const T cd3 = cd.mostSignificant();
|
||||
const T da3 = da.mostSignificant();
|
||||
const T ac3 = ac.mostSignificant();
|
||||
const T bd3 = bd.mostSignificant();
|
||||
det += ( ( (bex * bex + bey * bey + bez * bez) * ((cez * daeps + dez * aceps + aez * cdeps) + (ceztail * da3 + deztail * ac3 + aeztail * cd3))
|
||||
+ (dex * dex + dey * dey + dez * dez) * ((aez * bceps - bez * aceps + cez * abeps) + (aeztail * bc3 - beztail * ac3 + ceztail * ab3)) )
|
||||
- ( (aex * aex + aey * aey + aez * aez) * ((bez * cdeps - cez * bdeps + dez * bceps) + (beztail * cd3 - ceztail * bd3 + deztail * bc3))
|
||||
+ (cex * cex + cey * cey + cez * cez) * ((dez * abeps + aez * bdeps + bez * daeps) + (deztail * ab3 + aeztail * bd3 + beztail * da3)) ) )
|
||||
+ T(2) * ( ( (bex * bextail + bey * beytail + bez * beztail) * (cez * da3 + dez * ac3 + aez * cd3)
|
||||
+ (dex * dextail + dey * deytail + dez * deztail) * (aez * bc3 - bez * ac3 + cez * ab3))
|
||||
- ( (aex * aextail + aey * aeytail + aez * aeztail) * (bez * cd3 - cez * bd3 + dez * bc3)
|
||||
+ (cex * cextail + cey * ceytail + cez * ceztail) * (dez * ab3 + aez * bd3 + bez * da3)));
|
||||
if(std::abs(det) >= std::abs(errbound)) return det;
|
||||
return exact::insphere(pa, pb, pc, pd, pe);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
55
include/CDT/include/remove_at.hpp
Normal file
55
include/CDT/include/remove_at.hpp
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
#ifndef REMOVE_AT_HPP
|
||||
#define REMOVE_AT_HPP
|
||||
|
||||
// check if c++11 is supported
|
||||
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900)
|
||||
#define REMOVE_AT_CXX11_IS_SUPPORTED
|
||||
#elif !defined(__cplusplus) && !defined(_MSC_VER)
|
||||
typedef char couldnt_parse_cxx_standard[-1];
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
/*!
|
||||
* Remove elements in the range [first; last) with indices from the sorted
|
||||
* unique range [ii_first, ii_last)
|
||||
*/
|
||||
template <class ForwardIt, class SortUniqIndsFwdIt>
|
||||
inline ForwardIt remove_at(
|
||||
ForwardIt first,
|
||||
ForwardIt last,
|
||||
SortUniqIndsFwdIt ii_first,
|
||||
SortUniqIndsFwdIt ii_last)
|
||||
{
|
||||
if(ii_first == ii_last) // no indices-to-remove are given
|
||||
return last;
|
||||
typedef typename std::iterator_traits<ForwardIt>::difference_type diff_t;
|
||||
typedef typename std::iterator_traits<SortUniqIndsFwdIt>::value_type ind_t;
|
||||
ForwardIt destination = first + static_cast<diff_t>(*ii_first);
|
||||
while(ii_first != ii_last)
|
||||
{
|
||||
// advance to an index after a chunk of elements-to-keep
|
||||
for(ind_t cur = *ii_first++; ii_first != ii_last; ++ii_first)
|
||||
{
|
||||
const ind_t nxt = *ii_first;
|
||||
if(nxt - cur > 1)
|
||||
break;
|
||||
cur = nxt;
|
||||
}
|
||||
// move the chunk of elements-to-keep to new destination
|
||||
const ForwardIt source_first =
|
||||
first + static_cast<diff_t>(*(ii_first - 1)) + 1;
|
||||
const ForwardIt source_last =
|
||||
ii_first != ii_last ? first + static_cast<diff_t>(*ii_first) : last;
|
||||
#ifdef REMOVE_AT_CXX11_IS_SUPPORTED
|
||||
std::move(source_first, source_last, destination);
|
||||
#else
|
||||
std::copy(source_first, source_last, destination); // c++98 version
|
||||
#endif
|
||||
destination += source_last - source_first;
|
||||
}
|
||||
return destination;
|
||||
}
|
||||
|
||||
#endif // REMOVE_AT_HPP
|
||||
80
include/CDT/src/CDT.cpp
Normal file
80
include/CDT/src/CDT.cpp
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
/* 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
|
||||
* Explicit template instantiations for `float` and `double` coordinate types.
|
||||
*
|
||||
* Explicit instantiations are used when consuming as a compiled library.
|
||||
* In almost all of the cases 'float' and 'double' are sufficient.
|
||||
* Feel free to extend this with custom data types if needed.
|
||||
*/
|
||||
|
||||
#ifdef CDT_USE_AS_COMPILED_LIBRARY
|
||||
|
||||
#include "CDT.hpp"
|
||||
#include "CDTUtils.hpp"
|
||||
#include "InitializeWithGrid.h"
|
||||
#include "Triangulation.hpp"
|
||||
#include "VerifyTopology.h"
|
||||
|
||||
namespace CDT
|
||||
{
|
||||
|
||||
template struct CDT_EXPORT V2d<float>;
|
||||
template struct CDT_EXPORT V2d<double>;
|
||||
|
||||
template struct CDT_EXPORT Box2d<float>;
|
||||
template struct CDT_EXPORT Box2d<double>;
|
||||
|
||||
template class CDT_EXPORT Triangulation<float>;
|
||||
template class CDT_EXPORT Triangulation<double>;
|
||||
|
||||
template CDT_EXPORT DuplicatesInfo
|
||||
RemoveDuplicates<float>(std::vector<V2d<float> >&);
|
||||
template CDT_EXPORT DuplicatesInfo
|
||||
RemoveDuplicates<double>(std::vector<V2d<double> >&);
|
||||
|
||||
template CDT_EXPORT DuplicatesInfo RemoveDuplicatesAndRemapEdges<float>(
|
||||
std::vector<V2d<float> >&,
|
||||
std::vector<Edge>&);
|
||||
template CDT_EXPORT DuplicatesInfo RemoveDuplicatesAndRemapEdges<double>(
|
||||
std::vector<V2d<double> >&,
|
||||
std::vector<Edge>&);
|
||||
|
||||
template CDT_EXPORT bool
|
||||
verifyTopology<float>(const CDT::Triangulation<float>&);
|
||||
template CDT_EXPORT bool
|
||||
verifyTopology<double>(const CDT::Triangulation<double>&);
|
||||
|
||||
template CDT_EXPORT void initializeWithRegularGrid<float>(
|
||||
float,
|
||||
float,
|
||||
float,
|
||||
float,
|
||||
std::size_t,
|
||||
std::size_t,
|
||||
Triangulation<float>&);
|
||||
template CDT_EXPORT void initializeWithRegularGrid<double>(
|
||||
double,
|
||||
double,
|
||||
double,
|
||||
double,
|
||||
std::size_t,
|
||||
std::size_t,
|
||||
Triangulation<double>&);
|
||||
|
||||
template
|
||||
CDT_EXPORT float distance(const V2d<float>& a, const V2d<float>& b);
|
||||
template
|
||||
CDT_EXPORT double distance(const V2d<double>& a, const V2d<double>& b);
|
||||
|
||||
template
|
||||
CDT_EXPORT float distanceSquared(const V2d<float>& a, const V2d<float>& b);
|
||||
template
|
||||
CDT_EXPORT double distanceSquared(const V2d<double>& a, const V2d<double>& b);
|
||||
|
||||
} // namespace CDT
|
||||
|
||||
#endif
|
||||
1252
include/CDT/tests/cdt.test.cpp
Normal file
1252
include/CDT/tests/cdt.test.cpp
Normal file
File diff suppressed because it is too large
Load diff
12
include/CDT/tests/expected/154_1.txt
Normal file
12
include/CDT/tests/expected/154_1.txt
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
5
|
||||
0 1 3 4294967295 3 1
|
||||
0 3 2 0 4 4294967295
|
||||
1 2 4 4294967295 4 3
|
||||
1 4 3 2 4 0
|
||||
2 3 4 1 3 2
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
25
include/CDT/tests/expected/154_2.txt
Normal file
25
include/CDT/tests/expected/154_2.txt
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
17
|
||||
0 1 4 4294967295 4 1
|
||||
0 4 2 0 6 4294967295
|
||||
1 2 3 4294967295 7 3
|
||||
1 3 9 2 8 5
|
||||
1 7 4 5 14 0
|
||||
1 9 7 3 14 4
|
||||
2 4 6 1 13 7
|
||||
2 6 3 6 10 2
|
||||
3 4 9 9 14 3
|
||||
3 5 4 12 13 8
|
||||
3 6 8 7 15 11
|
||||
3 8 10 10 16 12
|
||||
3 10 5 11 16 9
|
||||
4 5 6 9 15 6
|
||||
4 7 9 4 5 8
|
||||
5 8 6 16 10 13
|
||||
5 10 8 12 11 15
|
||||
|
||||
1
|
||||
3 4
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
27
include/CDT/tests/expected/154_3.txt
Normal file
27
include/CDT/tests/expected/154_3.txt
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
19
|
||||
0 1 4 4294967295 6 2
|
||||
0 3 2 3 7 4294967295
|
||||
0 4 11 0 13 4
|
||||
0 9 3 4 11 1
|
||||
0 11 9 2 17 3
|
||||
1 2 10 4294967295 7 6
|
||||
1 10 4 5 14 0
|
||||
2 3 10 1 8 5
|
||||
3 5 10 10 14 7
|
||||
3 6 11 11 17 12
|
||||
3 8 5 12 16 8
|
||||
3 9 6 3 17 9
|
||||
3 11 8 9 18 10
|
||||
4 5 11 14 15 2
|
||||
4 10 5 6 8 13
|
||||
5 7 11 16 18 13
|
||||
5 8 7 10 18 15
|
||||
6 9 11 11 4 9
|
||||
7 8 11 16 12 15
|
||||
|
||||
1
|
||||
3 11
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
59
|
||||
0 1 31 4294967295 8 3
|
||||
0 3 7 3 13 2
|
||||
0 7 2 1 9 4294967295
|
||||
0 31 3 0 14 1
|
||||
1 2 12 4294967295 10 5
|
||||
1 12 13 4 38 6
|
||||
1 13 14 5 40 7
|
||||
1 14 27 6 43 8
|
||||
1 27 31 7 57 0
|
||||
2 7 8 2 25 10
|
||||
2 8 12 9 26 4
|
||||
3 4 5 14 15 12
|
||||
3 5 6 11 18 13
|
||||
3 6 7 12 23 1
|
||||
3 31 4 3 17 11
|
||||
4 24 5 16 19 11
|
||||
4 25 24 17 55 15
|
||||
4 31 25 14 57 16
|
||||
5 23 6 19 22 12
|
||||
5 24 23 15 55 18
|
||||
6 21 28 21 50 23
|
||||
6 22 21 22 52 20
|
||||
6 23 22 18 53 21
|
||||
6 28 7 20 24 13
|
||||
7 28 30 23 58 25
|
||||
7 30 8 24 28 9
|
||||
8 9 12 27 30 10
|
||||
8 29 9 28 35 26
|
||||
8 30 29 25 58 27
|
||||
9 10 11 31 36 30
|
||||
9 11 12 29 38 26
|
||||
9 17 10 32 37 29
|
||||
9 18 17 33 48 31
|
||||
9 19 18 34 45 32
|
||||
9 20 19 35 46 33
|
||||
9 29 20 27 51 34
|
||||
10 16 11 37 39 29
|
||||
10 17 16 31 48 36
|
||||
11 13 12 39 5 30
|
||||
11 16 13 36 40 38
|
||||
13 16 14 39 42 6
|
||||
14 15 26 42 47 43
|
||||
14 16 15 40 44 41
|
||||
14 26 27 41 56 7
|
||||
15 16 18 42 48 45
|
||||
15 18 19 44 33 46
|
||||
15 19 20 45 34 47
|
||||
15 20 26 46 49 41
|
||||
16 17 18 37 32 44
|
||||
20 21 26 50 52 47
|
||||
20 28 21 51 20 49
|
||||
20 29 28 35 58 50
|
||||
21 22 26 21 54 49
|
||||
22 23 25 22 55 54
|
||||
22 25 26 53 56 52
|
||||
23 24 25 19 16 53
|
||||
25 27 26 57 43 54
|
||||
25 31 27 17 8 56
|
||||
28 29 30 51 28 24
|
||||
|
||||
29
|
||||
3 4
|
||||
3 31
|
||||
4 5
|
||||
5 6
|
||||
6 7
|
||||
7 8
|
||||
8 9
|
||||
9 10
|
||||
10 11
|
||||
11 12
|
||||
12 13
|
||||
13 14
|
||||
14 15
|
||||
15 16
|
||||
16 17
|
||||
17 18
|
||||
18 19
|
||||
19 20
|
||||
20 21
|
||||
21 22
|
||||
22 23
|
||||
23 24
|
||||
24 25
|
||||
25 26
|
||||
26 27
|
||||
27 31
|
||||
28 29
|
||||
28 30
|
||||
29 30
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
29
|
||||
0 28 1 4294967295 3 4294967295
|
||||
1 21 2 2 5 4294967295
|
||||
1 22 21 3 4294967295 1
|
||||
1 28 22 0 28 2
|
||||
2 20 3 5 8 4294967295
|
||||
2 21 20 1 4294967295 4
|
||||
3 18 25 7 25 9
|
||||
3 19 18 8 4294967295 6
|
||||
3 20 19 4 4294967295 7
|
||||
3 25 4 6 10 4294967295
|
||||
4 25 27 9 4294967295 11
|
||||
4 27 5 10 13 4294967295
|
||||
5 26 6 13 18 4294967295
|
||||
5 27 26 11 4294967295 12
|
||||
6 14 7 15 20 4294967295
|
||||
6 15 14 16 4294967295 14
|
||||
6 16 15 17 4294967295 15
|
||||
6 17 16 18 4294967295 16
|
||||
6 26 17 12 26 17
|
||||
7 13 8 20 22 4294967295
|
||||
7 14 13 14 4294967295 19
|
||||
8 10 9 22 4294967295 4294967295
|
||||
8 13 10 19 23 21
|
||||
10 13 11 22 24 4294967295
|
||||
11 13 12 23 4294967295 4294967295
|
||||
17 25 18 26 6 4294967295
|
||||
17 26 25 18 4294967295 25
|
||||
22 24 23 28 4294967295 4294967295
|
||||
22 28 24 3 4294967295 27
|
||||
|
||||
29
|
||||
0 1
|
||||
0 28
|
||||
1 2
|
||||
2 3
|
||||
3 4
|
||||
4 5
|
||||
5 6
|
||||
6 7
|
||||
7 8
|
||||
8 9
|
||||
9 10
|
||||
10 11
|
||||
11 12
|
||||
12 13
|
||||
13 14
|
||||
14 15
|
||||
15 16
|
||||
16 17
|
||||
17 18
|
||||
18 19
|
||||
19 20
|
||||
20 21
|
||||
21 22
|
||||
22 23
|
||||
23 24
|
||||
24 28
|
||||
25 26
|
||||
25 27
|
||||
26 27
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
30
|
||||
0 28 1 4294967295 3 4294967295
|
||||
1 21 2 2 5 4294967295
|
||||
1 22 21 3 4294967295 1
|
||||
1 28 22 0 28 2
|
||||
2 20 3 5 8 4294967295
|
||||
2 21 20 1 4294967295 4
|
||||
3 18 25 7 25 9
|
||||
3 19 18 8 4294967295 6
|
||||
3 20 19 4 4294967295 7
|
||||
3 25 4 6 10 4294967295
|
||||
4 25 27 9 29 11
|
||||
4 27 5 10 13 4294967295
|
||||
5 26 6 13 18 4294967295
|
||||
5 27 26 11 29 12
|
||||
6 14 7 15 20 4294967295
|
||||
6 15 14 16 4294967295 14
|
||||
6 16 15 17 4294967295 15
|
||||
6 17 16 18 4294967295 16
|
||||
6 26 17 12 26 17
|
||||
7 13 8 20 22 4294967295
|
||||
7 14 13 14 4294967295 19
|
||||
8 10 9 22 4294967295 4294967295
|
||||
8 13 10 19 23 21
|
||||
10 13 11 22 24 4294967295
|
||||
11 13 12 23 4294967295 4294967295
|
||||
17 25 18 26 6 4294967295
|
||||
17 26 25 18 29 25
|
||||
22 24 23 28 4294967295 4294967295
|
||||
22 28 24 3 4294967295 27
|
||||
25 26 27 26 13 10
|
||||
|
||||
29
|
||||
0 1
|
||||
0 28
|
||||
1 2
|
||||
2 3
|
||||
3 4
|
||||
4 5
|
||||
5 6
|
||||
6 7
|
||||
7 8
|
||||
8 9
|
||||
9 10
|
||||
10 11
|
||||
11 12
|
||||
12 13
|
||||
13 14
|
||||
14 15
|
||||
15 16
|
||||
16 17
|
||||
17 18
|
||||
18 19
|
||||
19 20
|
||||
20 21
|
||||
21 22
|
||||
22 23
|
||||
23 24
|
||||
24 28
|
||||
25 26
|
||||
25 27
|
||||
26 27
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
48
|
||||
0 1 2 3 4 1
|
||||
0 2 3 0 7 2
|
||||
0 3 4 1 12 4294967295
|
||||
0 28 1 4294967295 6 0
|
||||
1 21 2 5 8 0
|
||||
1 22 21 6 44 4
|
||||
1 28 22 3 46 5
|
||||
2 20 3 8 11 1
|
||||
2 21 20 4 44 7
|
||||
3 18 25 10 39 12
|
||||
3 19 18 11 41 9
|
||||
3 20 19 7 42 10
|
||||
3 25 4 9 13 2
|
||||
4 25 27 12 47 14
|
||||
4 27 5 13 17 4294967295
|
||||
5 6 9 16 19 4294967295
|
||||
5 26 6 17 24 15
|
||||
5 27 26 14 47 16
|
||||
6 7 8 20 25 19
|
||||
6 8 9 18 27 15
|
||||
6 14 7 21 26 18
|
||||
6 15 14 22 37 20
|
||||
6 16 15 23 34 21
|
||||
6 17 16 24 35 22
|
||||
6 26 17 16 40 23
|
||||
7 13 8 26 28 18
|
||||
7 14 13 20 37 25
|
||||
8 10 9 28 4294967295 19
|
||||
8 13 10 25 29 27
|
||||
10 13 11 28 31 4294967295
|
||||
11 12 23 31 36 32
|
||||
11 13 12 29 33 30
|
||||
11 23 24 30 45 4294967295
|
||||
12 13 15 31 37 34
|
||||
12 15 16 33 22 35
|
||||
12 16 17 34 23 36
|
||||
12 17 23 35 38 30
|
||||
13 14 15 26 21 33
|
||||
17 18 23 39 41 36
|
||||
17 25 18 40 9 38
|
||||
17 26 25 24 47 39
|
||||
18 19 23 10 43 38
|
||||
19 20 22 11 44 43
|
||||
19 22 23 42 45 41
|
||||
20 21 22 8 5 42
|
||||
22 24 23 46 32 43
|
||||
22 28 24 6 4294967295 45
|
||||
25 26 27 40 17 13
|
||||
|
||||
29
|
||||
0 1
|
||||
0 28
|
||||
1 2
|
||||
2 3
|
||||
3 4
|
||||
4 5
|
||||
5 6
|
||||
6 7
|
||||
7 8
|
||||
8 9
|
||||
9 10
|
||||
10 11
|
||||
11 12
|
||||
12 13
|
||||
13 14
|
||||
14 15
|
||||
15 16
|
||||
16 17
|
||||
17 18
|
||||
18 19
|
||||
19 20
|
||||
20 21
|
||||
21 22
|
||||
22 23
|
||||
23 24
|
||||
24 28
|
||||
25 26
|
||||
25 27
|
||||
26 27
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
59
|
||||
0 1 31 4294967295 8 3
|
||||
0 3 7 3 13 2
|
||||
0 7 2 1 9 4294967295
|
||||
0 31 3 0 14 1
|
||||
1 2 12 4294967295 10 5
|
||||
1 12 13 4 38 6
|
||||
1 13 14 5 40 7
|
||||
1 14 27 6 43 8
|
||||
1 27 31 7 57 0
|
||||
2 7 8 2 25 10
|
||||
2 8 12 9 26 4
|
||||
3 4 5 14 15 12
|
||||
3 5 6 11 18 13
|
||||
3 6 7 12 23 1
|
||||
3 31 4 3 17 11
|
||||
4 24 5 16 19 11
|
||||
4 25 24 17 55 15
|
||||
4 31 25 14 57 16
|
||||
5 23 6 19 22 12
|
||||
5 24 23 15 55 18
|
||||
6 21 28 21 50 23
|
||||
6 22 21 22 52 20
|
||||
6 23 22 18 53 21
|
||||
6 28 7 20 24 13
|
||||
7 28 30 23 58 25
|
||||
7 30 8 24 28 9
|
||||
8 9 12 27 30 10
|
||||
8 29 9 28 35 26
|
||||
8 30 29 25 58 27
|
||||
9 10 11 31 36 30
|
||||
9 11 12 29 38 26
|
||||
9 17 10 32 37 29
|
||||
9 18 17 33 48 31
|
||||
9 19 18 34 45 32
|
||||
9 20 19 35 46 33
|
||||
9 29 20 27 51 34
|
||||
10 16 11 37 39 29
|
||||
10 17 16 31 48 36
|
||||
11 13 12 39 5 30
|
||||
11 16 13 36 40 38
|
||||
13 16 14 39 42 6
|
||||
14 15 26 42 47 43
|
||||
14 16 15 40 44 41
|
||||
14 26 27 41 56 7
|
||||
15 16 18 42 48 45
|
||||
15 18 19 44 33 46
|
||||
15 19 20 45 34 47
|
||||
15 20 26 46 49 41
|
||||
16 17 18 37 32 44
|
||||
20 21 26 50 52 47
|
||||
20 28 21 51 20 49
|
||||
20 29 28 35 58 50
|
||||
21 22 26 21 54 49
|
||||
22 23 25 22 55 54
|
||||
22 25 26 53 56 52
|
||||
23 24 25 19 16 53
|
||||
25 27 26 57 43 54
|
||||
25 31 27 17 8 56
|
||||
28 29 30 51 28 24
|
||||
|
||||
29
|
||||
3 4
|
||||
3 31
|
||||
4 5
|
||||
5 6
|
||||
6 7
|
||||
7 8
|
||||
8 9
|
||||
9 10
|
||||
10 11
|
||||
11 12
|
||||
12 13
|
||||
13 14
|
||||
14 15
|
||||
15 16
|
||||
16 17
|
||||
17 18
|
||||
18 19
|
||||
19 20
|
||||
20 21
|
||||
21 22
|
||||
22 23
|
||||
23 24
|
||||
24 25
|
||||
25 26
|
||||
26 27
|
||||
27 31
|
||||
28 29
|
||||
28 30
|
||||
29 30
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
29
|
||||
0 28 1 4294967295 3 4294967295
|
||||
1 21 2 2 5 4294967295
|
||||
1 22 21 3 4294967295 1
|
||||
1 28 22 0 28 2
|
||||
2 20 3 5 8 4294967295
|
||||
2 21 20 1 4294967295 4
|
||||
3 18 25 7 25 9
|
||||
3 19 18 8 4294967295 6
|
||||
3 20 19 4 4294967295 7
|
||||
3 25 4 6 10 4294967295
|
||||
4 25 27 9 4294967295 11
|
||||
4 27 5 10 13 4294967295
|
||||
5 26 6 13 18 4294967295
|
||||
5 27 26 11 4294967295 12
|
||||
6 14 7 15 20 4294967295
|
||||
6 15 14 16 4294967295 14
|
||||
6 16 15 17 4294967295 15
|
||||
6 17 16 18 4294967295 16
|
||||
6 26 17 12 26 17
|
||||
7 13 8 20 22 4294967295
|
||||
7 14 13 14 4294967295 19
|
||||
8 10 9 22 4294967295 4294967295
|
||||
8 13 10 19 23 21
|
||||
10 13 11 22 24 4294967295
|
||||
11 13 12 23 4294967295 4294967295
|
||||
17 25 18 26 6 4294967295
|
||||
17 26 25 18 4294967295 25
|
||||
22 24 23 28 4294967295 4294967295
|
||||
22 28 24 3 4294967295 27
|
||||
|
||||
29
|
||||
0 1
|
||||
0 28
|
||||
1 2
|
||||
2 3
|
||||
3 4
|
||||
4 5
|
||||
5 6
|
||||
6 7
|
||||
7 8
|
||||
8 9
|
||||
9 10
|
||||
10 11
|
||||
11 12
|
||||
12 13
|
||||
13 14
|
||||
14 15
|
||||
15 16
|
||||
16 17
|
||||
17 18
|
||||
18 19
|
||||
19 20
|
||||
20 21
|
||||
21 22
|
||||
22 23
|
||||
23 24
|
||||
24 28
|
||||
25 26
|
||||
25 27
|
||||
26 27
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
30
|
||||
0 28 1 4294967295 3 4294967295
|
||||
1 21 2 2 5 4294967295
|
||||
1 22 21 3 4294967295 1
|
||||
1 28 22 0 28 2
|
||||
2 20 3 5 8 4294967295
|
||||
2 21 20 1 4294967295 4
|
||||
3 18 25 7 25 9
|
||||
3 19 18 8 4294967295 6
|
||||
3 20 19 4 4294967295 7
|
||||
3 25 4 6 10 4294967295
|
||||
4 25 27 9 29 11
|
||||
4 27 5 10 13 4294967295
|
||||
5 26 6 13 18 4294967295
|
||||
5 27 26 11 29 12
|
||||
6 14 7 15 20 4294967295
|
||||
6 15 14 16 4294967295 14
|
||||
6 16 15 17 4294967295 15
|
||||
6 17 16 18 4294967295 16
|
||||
6 26 17 12 26 17
|
||||
7 13 8 20 22 4294967295
|
||||
7 14 13 14 4294967295 19
|
||||
8 10 9 22 4294967295 4294967295
|
||||
8 13 10 19 23 21
|
||||
10 13 11 22 24 4294967295
|
||||
11 13 12 23 4294967295 4294967295
|
||||
17 25 18 26 6 4294967295
|
||||
17 26 25 18 29 25
|
||||
22 24 23 28 4294967295 4294967295
|
||||
22 28 24 3 4294967295 27
|
||||
25 26 27 26 13 10
|
||||
|
||||
29
|
||||
0 1
|
||||
0 28
|
||||
1 2
|
||||
2 3
|
||||
3 4
|
||||
4 5
|
||||
5 6
|
||||
6 7
|
||||
7 8
|
||||
8 9
|
||||
9 10
|
||||
10 11
|
||||
11 12
|
||||
12 13
|
||||
13 14
|
||||
14 15
|
||||
15 16
|
||||
16 17
|
||||
17 18
|
||||
18 19
|
||||
19 20
|
||||
20 21
|
||||
21 22
|
||||
22 23
|
||||
23 24
|
||||
24 28
|
||||
25 26
|
||||
25 27
|
||||
26 27
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
48
|
||||
0 1 2 3 4 1
|
||||
0 2 3 0 7 2
|
||||
0 3 4 1 12 4294967295
|
||||
0 28 1 4294967295 6 0
|
||||
1 21 2 5 8 0
|
||||
1 22 21 6 44 4
|
||||
1 28 22 3 46 5
|
||||
2 20 3 8 11 1
|
||||
2 21 20 4 44 7
|
||||
3 18 25 10 39 12
|
||||
3 19 18 11 41 9
|
||||
3 20 19 7 42 10
|
||||
3 25 4 9 13 2
|
||||
4 25 27 12 47 14
|
||||
4 27 5 13 17 4294967295
|
||||
5 6 9 16 19 4294967295
|
||||
5 26 6 17 24 15
|
||||
5 27 26 14 47 16
|
||||
6 7 8 20 25 19
|
||||
6 8 9 18 27 15
|
||||
6 14 7 21 26 18
|
||||
6 15 14 22 37 20
|
||||
6 16 15 23 34 21
|
||||
6 17 16 24 35 22
|
||||
6 26 17 16 40 23
|
||||
7 13 8 26 28 18
|
||||
7 14 13 20 37 25
|
||||
8 10 9 28 4294967295 19
|
||||
8 13 10 25 29 27
|
||||
10 13 11 28 31 4294967295
|
||||
11 12 23 31 36 32
|
||||
11 13 12 29 33 30
|
||||
11 23 24 30 45 4294967295
|
||||
12 13 15 31 37 34
|
||||
12 15 16 33 22 35
|
||||
12 16 17 34 23 36
|
||||
12 17 23 35 38 30
|
||||
13 14 15 26 21 33
|
||||
17 18 23 39 41 36
|
||||
17 25 18 40 9 38
|
||||
17 26 25 24 47 39
|
||||
18 19 23 10 43 38
|
||||
19 20 22 11 44 43
|
||||
19 22 23 42 45 41
|
||||
20 21 22 8 5 42
|
||||
22 24 23 46 32 43
|
||||
22 28 24 6 4294967295 45
|
||||
25 26 27 40 17 13
|
||||
|
||||
29
|
||||
0 1
|
||||
0 28
|
||||
1 2
|
||||
2 3
|
||||
3 4
|
||||
4 5
|
||||
5 6
|
||||
6 7
|
||||
7 8
|
||||
8 9
|
||||
9 10
|
||||
10 11
|
||||
11 12
|
||||
12 13
|
||||
13 14
|
||||
14 15
|
||||
15 16
|
||||
16 17
|
||||
17 18
|
||||
18 19
|
||||
19 20
|
||||
20 21
|
||||
21 22
|
||||
22 23
|
||||
23 24
|
||||
24 28
|
||||
25 26
|
||||
25 27
|
||||
26 27
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
95
include/CDT/tests/expected/Capital A__auto_ignore_all.txt
Normal file
95
include/CDT/tests/expected/Capital A__auto_ignore_all.txt
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
59
|
||||
0 1 13 4294967295 7 2
|
||||
0 3 2 5 8 4294967295
|
||||
0 13 14 0 40 3
|
||||
0 14 27 2 43 4
|
||||
0 27 31 3 57 5
|
||||
0 31 3 4 14 1
|
||||
1 2 12 4294967295 10 7
|
||||
1 12 13 6 38 0
|
||||
2 3 7 1 13 9
|
||||
2 7 8 8 25 10
|
||||
2 8 12 9 26 6
|
||||
3 4 5 14 15 12
|
||||
3 5 6 11 18 13
|
||||
3 6 7 12 23 8
|
||||
3 31 4 5 17 11
|
||||
4 24 5 16 19 11
|
||||
4 25 24 17 55 15
|
||||
4 31 25 14 57 16
|
||||
5 23 6 19 22 12
|
||||
5 24 23 15 55 18
|
||||
6 21 28 21 50 23
|
||||
6 22 21 22 52 20
|
||||
6 23 22 18 53 21
|
||||
6 28 7 20 24 13
|
||||
7 28 30 23 58 25
|
||||
7 30 8 24 28 9
|
||||
8 9 12 27 30 10
|
||||
8 29 9 28 35 26
|
||||
8 30 29 25 58 27
|
||||
9 10 11 31 36 30
|
||||
9 11 12 29 38 26
|
||||
9 17 10 32 37 29
|
||||
9 18 17 33 48 31
|
||||
9 19 18 34 45 32
|
||||
9 20 19 35 46 33
|
||||
9 29 20 27 51 34
|
||||
10 16 11 37 39 29
|
||||
10 17 16 31 48 36
|
||||
11 13 12 39 7 30
|
||||
11 16 13 36 40 38
|
||||
13 16 14 39 42 2
|
||||
14 15 26 42 47 43
|
||||
14 16 15 40 44 41
|
||||
14 26 27 41 56 3
|
||||
15 16 18 42 48 45
|
||||
15 18 19 44 33 46
|
||||
15 19 20 45 34 47
|
||||
15 20 26 46 49 41
|
||||
16 17 18 37 32 44
|
||||
20 21 26 50 52 47
|
||||
20 28 21 51 20 49
|
||||
20 29 28 35 58 50
|
||||
21 22 26 21 54 49
|
||||
22 23 25 22 55 54
|
||||
22 25 26 53 56 52
|
||||
23 24 25 19 16 53
|
||||
25 27 26 57 43 54
|
||||
25 31 27 17 4 56
|
||||
28 29 30 51 28 24
|
||||
|
||||
29
|
||||
3 4
|
||||
3 31
|
||||
4 5
|
||||
5 6
|
||||
6 7
|
||||
7 8
|
||||
8 9
|
||||
9 10
|
||||
10 11
|
||||
11 12
|
||||
12 13
|
||||
13 14
|
||||
14 15
|
||||
15 16
|
||||
16 17
|
||||
17 18
|
||||
18 19
|
||||
19 20
|
||||
20 21
|
||||
21 22
|
||||
22 23
|
||||
23 24
|
||||
24 25
|
||||
25 26
|
||||
26 27
|
||||
27 31
|
||||
28 29
|
||||
28 30
|
||||
29 30
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
65
include/CDT/tests/expected/Capital A__auto_ignore_auto.txt
Normal file
65
include/CDT/tests/expected/Capital A__auto_ignore_auto.txt
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
29
|
||||
0 28 1 4294967295 3 4294967295
|
||||
1 21 2 2 5 4294967295
|
||||
1 22 21 3 4294967295 1
|
||||
1 28 22 0 28 2
|
||||
2 20 3 5 8 4294967295
|
||||
2 21 20 1 4294967295 4
|
||||
3 18 25 7 25 9
|
||||
3 19 18 8 4294967295 6
|
||||
3 20 19 4 4294967295 7
|
||||
3 25 4 6 10 4294967295
|
||||
4 25 27 9 4294967295 11
|
||||
4 27 5 10 13 4294967295
|
||||
5 26 6 13 18 4294967295
|
||||
5 27 26 11 4294967295 12
|
||||
6 14 7 15 20 4294967295
|
||||
6 15 14 16 4294967295 14
|
||||
6 16 15 17 4294967295 15
|
||||
6 17 16 18 4294967295 16
|
||||
6 26 17 12 26 17
|
||||
7 13 8 20 22 4294967295
|
||||
7 14 13 14 4294967295 19
|
||||
8 10 9 22 4294967295 4294967295
|
||||
8 13 10 19 23 21
|
||||
10 13 11 22 24 4294967295
|
||||
11 13 12 23 4294967295 4294967295
|
||||
17 25 18 26 6 4294967295
|
||||
17 26 25 18 4294967295 25
|
||||
22 24 23 28 4294967295 4294967295
|
||||
22 28 24 3 4294967295 27
|
||||
|
||||
29
|
||||
0 1
|
||||
0 28
|
||||
1 2
|
||||
2 3
|
||||
3 4
|
||||
4 5
|
||||
5 6
|
||||
6 7
|
||||
7 8
|
||||
8 9
|
||||
9 10
|
||||
10 11
|
||||
11 12
|
||||
12 13
|
||||
13 14
|
||||
14 15
|
||||
15 16
|
||||
16 17
|
||||
17 18
|
||||
18 19
|
||||
19 20
|
||||
20 21
|
||||
21 22
|
||||
22 23
|
||||
23 24
|
||||
24 28
|
||||
25 26
|
||||
25 27
|
||||
26 27
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
66
include/CDT/tests/expected/Capital A__auto_ignore_outer.txt
Normal file
66
include/CDT/tests/expected/Capital A__auto_ignore_outer.txt
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
30
|
||||
0 28 1 4294967295 3 4294967295
|
||||
1 21 2 2 5 4294967295
|
||||
1 22 21 3 4294967295 1
|
||||
1 28 22 0 28 2
|
||||
2 20 3 5 8 4294967295
|
||||
2 21 20 1 4294967295 4
|
||||
3 18 25 7 25 9
|
||||
3 19 18 8 4294967295 6
|
||||
3 20 19 4 4294967295 7
|
||||
3 25 4 6 10 4294967295
|
||||
4 25 27 9 29 11
|
||||
4 27 5 10 13 4294967295
|
||||
5 26 6 13 18 4294967295
|
||||
5 27 26 11 29 12
|
||||
6 14 7 15 20 4294967295
|
||||
6 15 14 16 4294967295 14
|
||||
6 16 15 17 4294967295 15
|
||||
6 17 16 18 4294967295 16
|
||||
6 26 17 12 26 17
|
||||
7 13 8 20 22 4294967295
|
||||
7 14 13 14 4294967295 19
|
||||
8 10 9 22 4294967295 4294967295
|
||||
8 13 10 19 23 21
|
||||
10 13 11 22 24 4294967295
|
||||
11 13 12 23 4294967295 4294967295
|
||||
17 25 18 26 6 4294967295
|
||||
17 26 25 18 29 25
|
||||
22 24 23 28 4294967295 4294967295
|
||||
22 28 24 3 4294967295 27
|
||||
25 26 27 26 13 10
|
||||
|
||||
29
|
||||
0 1
|
||||
0 28
|
||||
1 2
|
||||
2 3
|
||||
3 4
|
||||
4 5
|
||||
5 6
|
||||
6 7
|
||||
7 8
|
||||
8 9
|
||||
9 10
|
||||
10 11
|
||||
11 12
|
||||
12 13
|
||||
13 14
|
||||
14 15
|
||||
15 16
|
||||
16 17
|
||||
17 18
|
||||
18 19
|
||||
19 20
|
||||
20 21
|
||||
21 22
|
||||
22 23
|
||||
23 24
|
||||
24 28
|
||||
25 26
|
||||
25 27
|
||||
26 27
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
84
include/CDT/tests/expected/Capital A__auto_ignore_super.txt
Normal file
84
include/CDT/tests/expected/Capital A__auto_ignore_super.txt
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
48
|
||||
0 1 2 3 4 1
|
||||
0 2 3 0 7 2
|
||||
0 3 4 1 12 4294967295
|
||||
0 28 1 4294967295 6 0
|
||||
1 21 2 5 8 0
|
||||
1 22 21 6 44 4
|
||||
1 28 22 3 46 5
|
||||
2 20 3 8 11 1
|
||||
2 21 20 4 44 7
|
||||
3 18 25 10 39 12
|
||||
3 19 18 11 41 9
|
||||
3 20 19 7 42 10
|
||||
3 25 4 9 13 2
|
||||
4 25 27 12 47 14
|
||||
4 27 5 13 17 4294967295
|
||||
5 6 9 16 19 4294967295
|
||||
5 26 6 17 24 15
|
||||
5 27 26 14 47 16
|
||||
6 7 8 20 25 19
|
||||
6 8 9 18 27 15
|
||||
6 14 7 21 26 18
|
||||
6 15 14 22 37 20
|
||||
6 16 15 23 34 21
|
||||
6 17 16 24 35 22
|
||||
6 26 17 16 40 23
|
||||
7 13 8 26 28 18
|
||||
7 14 13 20 37 25
|
||||
8 10 9 28 4294967295 19
|
||||
8 13 10 25 29 27
|
||||
10 13 11 28 31 4294967295
|
||||
11 12 23 31 36 32
|
||||
11 13 12 29 33 30
|
||||
11 23 24 30 45 4294967295
|
||||
12 13 15 31 37 34
|
||||
12 15 16 33 22 35
|
||||
12 16 17 34 23 36
|
||||
12 17 23 35 38 30
|
||||
13 14 15 26 21 33
|
||||
17 18 23 39 41 36
|
||||
17 25 18 40 9 38
|
||||
17 26 25 24 47 39
|
||||
18 19 23 10 43 38
|
||||
19 20 22 11 44 43
|
||||
19 22 23 42 45 41
|
||||
20 21 22 8 5 42
|
||||
22 24 23 46 32 43
|
||||
22 28 24 6 4294967295 45
|
||||
25 26 27 40 17 13
|
||||
|
||||
29
|
||||
0 1
|
||||
0 28
|
||||
1 2
|
||||
2 3
|
||||
3 4
|
||||
4 5
|
||||
5 6
|
||||
6 7
|
||||
7 8
|
||||
8 9
|
||||
9 10
|
||||
10 11
|
||||
11 12
|
||||
12 13
|
||||
13 14
|
||||
14 15
|
||||
15 16
|
||||
16 17
|
||||
17 18
|
||||
18 19
|
||||
19 20
|
||||
20 21
|
||||
21 22
|
||||
22 23
|
||||
23 24
|
||||
24 28
|
||||
25 26
|
||||
25 27
|
||||
26 27
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
95
include/CDT/tests/expected/Capital A__auto_resolve_all.txt
Normal file
95
include/CDT/tests/expected/Capital A__auto_resolve_all.txt
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
59
|
||||
0 1 13 4294967295 7 2
|
||||
0 3 2 5 8 4294967295
|
||||
0 13 14 0 40 3
|
||||
0 14 27 2 43 4
|
||||
0 27 31 3 57 5
|
||||
0 31 3 4 14 1
|
||||
1 2 12 4294967295 10 7
|
||||
1 12 13 6 38 0
|
||||
2 3 7 1 13 9
|
||||
2 7 8 8 25 10
|
||||
2 8 12 9 26 6
|
||||
3 4 5 14 15 12
|
||||
3 5 6 11 18 13
|
||||
3 6 7 12 23 8
|
||||
3 31 4 5 17 11
|
||||
4 24 5 16 19 11
|
||||
4 25 24 17 55 15
|
||||
4 31 25 14 57 16
|
||||
5 23 6 19 22 12
|
||||
5 24 23 15 55 18
|
||||
6 21 28 21 50 23
|
||||
6 22 21 22 52 20
|
||||
6 23 22 18 53 21
|
||||
6 28 7 20 24 13
|
||||
7 28 30 23 58 25
|
||||
7 30 8 24 28 9
|
||||
8 9 12 27 30 10
|
||||
8 29 9 28 35 26
|
||||
8 30 29 25 58 27
|
||||
9 10 11 31 36 30
|
||||
9 11 12 29 38 26
|
||||
9 17 10 32 37 29
|
||||
9 18 17 33 48 31
|
||||
9 19 18 34 45 32
|
||||
9 20 19 35 46 33
|
||||
9 29 20 27 51 34
|
||||
10 16 11 37 39 29
|
||||
10 17 16 31 48 36
|
||||
11 13 12 39 7 30
|
||||
11 16 13 36 40 38
|
||||
13 16 14 39 42 2
|
||||
14 15 26 42 47 43
|
||||
14 16 15 40 44 41
|
||||
14 26 27 41 56 3
|
||||
15 16 18 42 48 45
|
||||
15 18 19 44 33 46
|
||||
15 19 20 45 34 47
|
||||
15 20 26 46 49 41
|
||||
16 17 18 37 32 44
|
||||
20 21 26 50 52 47
|
||||
20 28 21 51 20 49
|
||||
20 29 28 35 58 50
|
||||
21 22 26 21 54 49
|
||||
22 23 25 22 55 54
|
||||
22 25 26 53 56 52
|
||||
23 24 25 19 16 53
|
||||
25 27 26 57 43 54
|
||||
25 31 27 17 4 56
|
||||
28 29 30 51 28 24
|
||||
|
||||
29
|
||||
3 4
|
||||
3 31
|
||||
4 5
|
||||
5 6
|
||||
6 7
|
||||
7 8
|
||||
8 9
|
||||
9 10
|
||||
10 11
|
||||
11 12
|
||||
12 13
|
||||
13 14
|
||||
14 15
|
||||
15 16
|
||||
16 17
|
||||
17 18
|
||||
18 19
|
||||
19 20
|
||||
20 21
|
||||
21 22
|
||||
22 23
|
||||
23 24
|
||||
24 25
|
||||
25 26
|
||||
26 27
|
||||
27 31
|
||||
28 29
|
||||
28 30
|
||||
29 30
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
65
include/CDT/tests/expected/Capital A__auto_resolve_auto.txt
Normal file
65
include/CDT/tests/expected/Capital A__auto_resolve_auto.txt
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
29
|
||||
0 28 1 4294967295 3 4294967295
|
||||
1 21 2 2 5 4294967295
|
||||
1 22 21 3 4294967295 1
|
||||
1 28 22 0 28 2
|
||||
2 20 3 5 8 4294967295
|
||||
2 21 20 1 4294967295 4
|
||||
3 18 25 7 25 9
|
||||
3 19 18 8 4294967295 6
|
||||
3 20 19 4 4294967295 7
|
||||
3 25 4 6 10 4294967295
|
||||
4 25 27 9 4294967295 11
|
||||
4 27 5 10 13 4294967295
|
||||
5 26 6 13 18 4294967295
|
||||
5 27 26 11 4294967295 12
|
||||
6 14 7 15 20 4294967295
|
||||
6 15 14 16 4294967295 14
|
||||
6 16 15 17 4294967295 15
|
||||
6 17 16 18 4294967295 16
|
||||
6 26 17 12 26 17
|
||||
7 13 8 20 22 4294967295
|
||||
7 14 13 14 4294967295 19
|
||||
8 10 9 22 4294967295 4294967295
|
||||
8 13 10 19 23 21
|
||||
10 13 11 22 24 4294967295
|
||||
11 13 12 23 4294967295 4294967295
|
||||
17 25 18 26 6 4294967295
|
||||
17 26 25 18 4294967295 25
|
||||
22 24 23 28 4294967295 4294967295
|
||||
22 28 24 3 4294967295 27
|
||||
|
||||
29
|
||||
0 1
|
||||
0 28
|
||||
1 2
|
||||
2 3
|
||||
3 4
|
||||
4 5
|
||||
5 6
|
||||
6 7
|
||||
7 8
|
||||
8 9
|
||||
9 10
|
||||
10 11
|
||||
11 12
|
||||
12 13
|
||||
13 14
|
||||
14 15
|
||||
15 16
|
||||
16 17
|
||||
17 18
|
||||
18 19
|
||||
19 20
|
||||
20 21
|
||||
21 22
|
||||
22 23
|
||||
23 24
|
||||
24 28
|
||||
25 26
|
||||
25 27
|
||||
26 27
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
66
include/CDT/tests/expected/Capital A__auto_resolve_outer.txt
Normal file
66
include/CDT/tests/expected/Capital A__auto_resolve_outer.txt
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
30
|
||||
0 28 1 4294967295 3 4294967295
|
||||
1 21 2 2 5 4294967295
|
||||
1 22 21 3 4294967295 1
|
||||
1 28 22 0 28 2
|
||||
2 20 3 5 8 4294967295
|
||||
2 21 20 1 4294967295 4
|
||||
3 18 25 7 25 9
|
||||
3 19 18 8 4294967295 6
|
||||
3 20 19 4 4294967295 7
|
||||
3 25 4 6 10 4294967295
|
||||
4 25 27 9 29 11
|
||||
4 27 5 10 13 4294967295
|
||||
5 26 6 13 18 4294967295
|
||||
5 27 26 11 29 12
|
||||
6 14 7 15 20 4294967295
|
||||
6 15 14 16 4294967295 14
|
||||
6 16 15 17 4294967295 15
|
||||
6 17 16 18 4294967295 16
|
||||
6 26 17 12 26 17
|
||||
7 13 8 20 22 4294967295
|
||||
7 14 13 14 4294967295 19
|
||||
8 10 9 22 4294967295 4294967295
|
||||
8 13 10 19 23 21
|
||||
10 13 11 22 24 4294967295
|
||||
11 13 12 23 4294967295 4294967295
|
||||
17 25 18 26 6 4294967295
|
||||
17 26 25 18 29 25
|
||||
22 24 23 28 4294967295 4294967295
|
||||
22 28 24 3 4294967295 27
|
||||
25 26 27 26 13 10
|
||||
|
||||
29
|
||||
0 1
|
||||
0 28
|
||||
1 2
|
||||
2 3
|
||||
3 4
|
||||
4 5
|
||||
5 6
|
||||
6 7
|
||||
7 8
|
||||
8 9
|
||||
9 10
|
||||
10 11
|
||||
11 12
|
||||
12 13
|
||||
13 14
|
||||
14 15
|
||||
15 16
|
||||
16 17
|
||||
17 18
|
||||
18 19
|
||||
19 20
|
||||
20 21
|
||||
21 22
|
||||
22 23
|
||||
23 24
|
||||
24 28
|
||||
25 26
|
||||
25 27
|
||||
26 27
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
84
include/CDT/tests/expected/Capital A__auto_resolve_super.txt
Normal file
84
include/CDT/tests/expected/Capital A__auto_resolve_super.txt
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
48
|
||||
0 1 2 3 4 1
|
||||
0 2 3 0 7 2
|
||||
0 3 4 1 12 4294967295
|
||||
0 28 1 4294967295 6 0
|
||||
1 21 2 5 8 0
|
||||
1 22 21 6 44 4
|
||||
1 28 22 3 46 5
|
||||
2 20 3 8 11 1
|
||||
2 21 20 4 44 7
|
||||
3 18 25 10 39 12
|
||||
3 19 18 11 41 9
|
||||
3 20 19 7 42 10
|
||||
3 25 4 9 13 2
|
||||
4 25 27 12 47 14
|
||||
4 27 5 13 17 4294967295
|
||||
5 6 9 16 19 4294967295
|
||||
5 26 6 17 24 15
|
||||
5 27 26 14 47 16
|
||||
6 7 8 20 25 19
|
||||
6 8 9 18 27 15
|
||||
6 14 7 21 26 18
|
||||
6 15 14 22 37 20
|
||||
6 16 15 23 34 21
|
||||
6 17 16 24 35 22
|
||||
6 26 17 16 40 23
|
||||
7 13 8 26 28 18
|
||||
7 14 13 20 37 25
|
||||
8 10 9 28 4294967295 19
|
||||
8 13 10 25 29 27
|
||||
10 13 11 28 31 4294967295
|
||||
11 12 23 31 36 32
|
||||
11 13 12 29 33 30
|
||||
11 23 24 30 45 4294967295
|
||||
12 13 15 31 37 34
|
||||
12 15 16 33 22 35
|
||||
12 16 17 34 23 36
|
||||
12 17 23 35 38 30
|
||||
13 14 15 26 21 33
|
||||
17 18 23 39 41 36
|
||||
17 25 18 40 9 38
|
||||
17 26 25 24 47 39
|
||||
18 19 23 10 43 38
|
||||
19 20 22 11 44 43
|
||||
19 22 23 42 45 41
|
||||
20 21 22 8 5 42
|
||||
22 24 23 46 32 43
|
||||
22 28 24 6 4294967295 45
|
||||
25 26 27 40 17 13
|
||||
|
||||
29
|
||||
0 1
|
||||
0 28
|
||||
1 2
|
||||
2 3
|
||||
3 4
|
||||
4 5
|
||||
5 6
|
||||
6 7
|
||||
7 8
|
||||
8 9
|
||||
9 10
|
||||
10 11
|
||||
11 12
|
||||
12 13
|
||||
13 14
|
||||
14 15
|
||||
15 16
|
||||
16 17
|
||||
17 18
|
||||
18 19
|
||||
19 20
|
||||
20 21
|
||||
21 22
|
||||
22 23
|
||||
23 24
|
||||
24 28
|
||||
25 26
|
||||
25 27
|
||||
26 27
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
31
|
||||
0 28 1 4294967295 3 4294967295
|
||||
1 21 2 2 5 4294967295
|
||||
1 22 21 3 4294967295 1
|
||||
1 28 22 0 28 2
|
||||
2 20 3 5 8 4294967295
|
||||
2 21 20 1 4294967295 4
|
||||
3 18 25 7 25 9
|
||||
3 19 18 8 4294967295 6
|
||||
3 20 19 4 4294967295 7
|
||||
3 25 29 6 29 4294967295
|
||||
4 27 5 11 13 4294967295
|
||||
4 29 27 4294967295 30 10
|
||||
5 26 6 13 18 4294967295
|
||||
5 27 26 10 4294967295 12
|
||||
6 14 7 15 20 4294967295
|
||||
6 15 14 16 4294967295 14
|
||||
6 16 15 17 4294967295 15
|
||||
6 17 16 18 4294967295 16
|
||||
6 26 17 12 26 17
|
||||
7 13 8 20 22 4294967295
|
||||
7 14 13 14 4294967295 19
|
||||
8 10 9 22 4294967295 4294967295
|
||||
8 13 10 19 23 21
|
||||
10 13 11 22 24 4294967295
|
||||
11 13 12 23 4294967295 4294967295
|
||||
17 25 18 26 6 4294967295
|
||||
17 26 25 18 4294967295 25
|
||||
22 24 23 28 4294967295 4294967295
|
||||
22 28 24 3 4294967295 27
|
||||
25 30 29 4294967295 30 9
|
||||
27 29 30 11 29 4294967295
|
||||
|
||||
31
|
||||
0 1
|
||||
0 28
|
||||
1 2
|
||||
2 3
|
||||
3 29
|
||||
4 5
|
||||
4 29
|
||||
5 6
|
||||
6 7
|
||||
7 8
|
||||
8 9
|
||||
9 10
|
||||
10 11
|
||||
11 12
|
||||
12 13
|
||||
13 14
|
||||
14 15
|
||||
15 16
|
||||
16 17
|
||||
17 18
|
||||
18 19
|
||||
19 20
|
||||
20 21
|
||||
21 22
|
||||
22 23
|
||||
23 24
|
||||
24 28
|
||||
25 26
|
||||
25 30
|
||||
26 27
|
||||
27 30
|
||||
|
||||
0
|
||||
|
||||
4
|
||||
3 29
|
||||
1
|
||||
3 4
|
||||
4 29
|
||||
1
|
||||
3 4
|
||||
25 30
|
||||
1
|
||||
25 27
|
||||
27 30
|
||||
1
|
||||
25 27
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
27
|
||||
0 1 11 4294967295 5 3
|
||||
0 3 2 2 6 4294967295
|
||||
0 4 3 3 8 1
|
||||
0 11 4 0 15 2
|
||||
1 2 12 4294967295 7 5
|
||||
1 12 11 4 24 0
|
||||
2 3 13 1 12 7
|
||||
2 13 12 6 25 4
|
||||
3 4 5 2 14 9
|
||||
3 5 7 8 16 10
|
||||
3 7 12 9 20 11
|
||||
3 12 15 10 25 13
|
||||
3 14 13 13 26 6
|
||||
3 15 14 11 26 12
|
||||
4 6 5 15 16 8
|
||||
4 11 6 3 19 14
|
||||
5 6 7 14 18 9
|
||||
6 8 9 19 21 18
|
||||
6 9 7 17 20 16
|
||||
6 11 8 15 22 17
|
||||
7 9 12 18 23 10
|
||||
8 10 9 22 23 17
|
||||
8 11 10 19 24 21
|
||||
9 10 12 21 24 20
|
||||
10 11 12 22 5 23
|
||||
12 13 15 7 26 11
|
||||
13 14 15 12 13 25
|
||||
|
||||
9
|
||||
3 4
|
||||
3 12
|
||||
4 5
|
||||
5 6
|
||||
6 8
|
||||
8 9
|
||||
9 10
|
||||
10 11
|
||||
11 12
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
9
|
||||
0 1 2 4294967295 4294967295 1
|
||||
0 2 4 0 3 2
|
||||
0 4 9 1 6 4294967295
|
||||
2 3 4 4294967295 5 1
|
||||
3 5 6 4294967295 4294967295 5
|
||||
3 6 4 4 6 3
|
||||
4 6 9 5 7 2
|
||||
6 7 9 4294967295 8 6
|
||||
7 8 9 4294967295 4294967295 7
|
||||
|
||||
9
|
||||
0 1
|
||||
0 9
|
||||
1 2
|
||||
2 3
|
||||
3 5
|
||||
5 6
|
||||
6 7
|
||||
7 8
|
||||
8 9
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
9
|
||||
0 1 2 4294967295 4294967295 1
|
||||
0 2 4 0 3 2
|
||||
0 4 9 1 6 4294967295
|
||||
2 3 4 4294967295 5 1
|
||||
3 5 6 4294967295 4294967295 5
|
||||
3 6 4 4 6 3
|
||||
4 6 9 5 7 2
|
||||
6 7 9 4294967295 8 6
|
||||
7 8 9 4294967295 4294967295 7
|
||||
|
||||
9
|
||||
0 1
|
||||
0 9
|
||||
1 2
|
||||
2 3
|
||||
3 5
|
||||
5 6
|
||||
6 7
|
||||
7 8
|
||||
8 9
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
19
|
||||
0 1 2 4294967295 6 1
|
||||
0 2 4 0 8 2
|
||||
0 4 9 1 12 3
|
||||
0 9 12 2 17 5
|
||||
0 11 10 5 18 4294967295
|
||||
0 12 11 3 18 4
|
||||
1 3 2 7 8 0
|
||||
1 8 3 4294967295 11 6
|
||||
2 3 4 6 10 1
|
||||
3 5 6 11 13 10
|
||||
3 6 4 9 12 8
|
||||
3 8 5 7 14 9
|
||||
4 6 9 10 15 2
|
||||
5 7 6 14 15 9
|
||||
5 8 7 11 16 13
|
||||
6 7 9 13 16 12
|
||||
7 8 9 14 4294967295 15
|
||||
9 10 12 4294967295 18 3
|
||||
10 11 12 4 5 17
|
||||
|
||||
9
|
||||
0 1
|
||||
0 9
|
||||
1 2
|
||||
2 3
|
||||
3 5
|
||||
5 6
|
||||
6 7
|
||||
7 8
|
||||
8 9
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
27
|
||||
0 1 11 4294967295 5 3
|
||||
0 3 2 2 6 4294967295
|
||||
0 4 3 3 8 1
|
||||
0 11 4 0 15 2
|
||||
1 2 12 4294967295 7 5
|
||||
1 12 11 4 24 0
|
||||
2 3 13 1 12 7
|
||||
2 13 12 6 25 4
|
||||
3 4 5 2 14 9
|
||||
3 5 7 8 16 10
|
||||
3 7 12 9 20 11
|
||||
3 12 15 10 25 13
|
||||
3 14 13 13 26 6
|
||||
3 15 14 11 26 12
|
||||
4 6 5 15 16 8
|
||||
4 11 6 3 19 14
|
||||
5 6 7 14 18 9
|
||||
6 8 9 19 21 18
|
||||
6 9 7 17 20 16
|
||||
6 11 8 15 22 17
|
||||
7 9 12 18 23 10
|
||||
8 10 9 22 23 17
|
||||
8 11 10 19 24 21
|
||||
9 10 12 21 24 20
|
||||
10 11 12 22 5 23
|
||||
12 13 15 7 26 11
|
||||
13 14 15 12 13 25
|
||||
|
||||
9
|
||||
3 4
|
||||
3 12
|
||||
4 5
|
||||
5 6
|
||||
6 8
|
||||
8 9
|
||||
9 10
|
||||
10 11
|
||||
11 12
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
9
|
||||
0 1 2 4294967295 4294967295 1
|
||||
0 2 4 0 3 2
|
||||
0 4 9 1 6 4294967295
|
||||
2 3 4 4294967295 5 1
|
||||
3 5 6 4294967295 4294967295 5
|
||||
3 6 4 4 6 3
|
||||
4 6 9 5 7 2
|
||||
6 7 9 4294967295 8 6
|
||||
7 8 9 4294967295 4294967295 7
|
||||
|
||||
9
|
||||
0 1
|
||||
0 9
|
||||
1 2
|
||||
2 3
|
||||
3 5
|
||||
5 6
|
||||
6 7
|
||||
7 8
|
||||
8 9
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
9
|
||||
0 1 2 4294967295 4294967295 1
|
||||
0 2 4 0 3 2
|
||||
0 4 9 1 6 4294967295
|
||||
2 3 4 4294967295 5 1
|
||||
3 5 6 4294967295 4294967295 5
|
||||
3 6 4 4 6 3
|
||||
4 6 9 5 7 2
|
||||
6 7 9 4294967295 8 6
|
||||
7 8 9 4294967295 4294967295 7
|
||||
|
||||
9
|
||||
0 1
|
||||
0 9
|
||||
1 2
|
||||
2 3
|
||||
3 5
|
||||
5 6
|
||||
6 7
|
||||
7 8
|
||||
8 9
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
19
|
||||
0 1 2 4294967295 6 1
|
||||
0 2 4 0 8 2
|
||||
0 4 9 1 12 3
|
||||
0 9 12 2 17 5
|
||||
0 11 10 5 18 4294967295
|
||||
0 12 11 3 18 4
|
||||
1 3 2 7 8 0
|
||||
1 8 3 4294967295 11 6
|
||||
2 3 4 6 10 1
|
||||
3 5 6 11 13 10
|
||||
3 6 4 9 12 8
|
||||
3 8 5 7 14 9
|
||||
4 6 9 10 15 2
|
||||
5 7 6 14 15 9
|
||||
5 8 7 11 16 13
|
||||
6 7 9 13 16 12
|
||||
7 8 9 14 4294967295 15
|
||||
9 10 12 4294967295 18 3
|
||||
10 11 12 4 5 17
|
||||
|
||||
9
|
||||
0 1
|
||||
0 9
|
||||
1 2
|
||||
2 3
|
||||
3 5
|
||||
5 6
|
||||
6 7
|
||||
7 8
|
||||
8 9
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
43
include/CDT/tests/expected/Hanging2__auto_ignore_all.txt
Normal file
43
include/CDT/tests/expected/Hanging2__auto_ignore_all.txt
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
27
|
||||
0 1 11 4294967295 5 3
|
||||
0 3 2 2 6 4294967295
|
||||
0 4 3 3 8 1
|
||||
0 11 4 0 15 2
|
||||
1 2 12 4294967295 7 5
|
||||
1 12 11 4 24 0
|
||||
2 3 13 1 12 7
|
||||
2 13 12 6 25 4
|
||||
3 4 5 2 14 9
|
||||
3 5 7 8 16 10
|
||||
3 7 12 9 20 11
|
||||
3 12 15 10 25 13
|
||||
3 14 13 13 26 6
|
||||
3 15 14 11 26 12
|
||||
4 6 5 15 16 8
|
||||
4 11 6 3 19 14
|
||||
5 6 7 14 18 9
|
||||
6 8 9 19 21 18
|
||||
6 9 7 17 20 16
|
||||
6 11 8 15 22 17
|
||||
7 9 12 18 23 10
|
||||
8 10 9 22 23 17
|
||||
8 11 10 19 24 21
|
||||
9 10 12 21 24 20
|
||||
10 11 12 22 5 23
|
||||
12 13 15 7 26 11
|
||||
13 14 15 12 13 25
|
||||
|
||||
9
|
||||
3 4
|
||||
3 12
|
||||
4 5
|
||||
5 6
|
||||
6 8
|
||||
8 9
|
||||
9 10
|
||||
10 11
|
||||
11 12
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
25
include/CDT/tests/expected/Hanging2__auto_ignore_auto.txt
Normal file
25
include/CDT/tests/expected/Hanging2__auto_ignore_auto.txt
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
9
|
||||
0 1 2 4294967295 4294967295 1
|
||||
0 2 4 0 3 2
|
||||
0 4 9 1 6 4294967295
|
||||
2 3 4 4294967295 5 1
|
||||
3 5 6 4294967295 4294967295 5
|
||||
3 6 4 4 6 3
|
||||
4 6 9 5 7 2
|
||||
6 7 9 4294967295 8 6
|
||||
7 8 9 4294967295 4294967295 7
|
||||
|
||||
9
|
||||
0 1
|
||||
0 9
|
||||
1 2
|
||||
2 3
|
||||
3 5
|
||||
5 6
|
||||
6 7
|
||||
7 8
|
||||
8 9
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
25
include/CDT/tests/expected/Hanging2__auto_ignore_outer.txt
Normal file
25
include/CDT/tests/expected/Hanging2__auto_ignore_outer.txt
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
9
|
||||
0 1 2 4294967295 4294967295 1
|
||||
0 2 4 0 3 2
|
||||
0 4 9 1 6 4294967295
|
||||
2 3 4 4294967295 5 1
|
||||
3 5 6 4294967295 4294967295 5
|
||||
3 6 4 4 6 3
|
||||
4 6 9 5 7 2
|
||||
6 7 9 4294967295 8 6
|
||||
7 8 9 4294967295 4294967295 7
|
||||
|
||||
9
|
||||
0 1
|
||||
0 9
|
||||
1 2
|
||||
2 3
|
||||
3 5
|
||||
5 6
|
||||
6 7
|
||||
7 8
|
||||
8 9
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
35
include/CDT/tests/expected/Hanging2__auto_ignore_super.txt
Normal file
35
include/CDT/tests/expected/Hanging2__auto_ignore_super.txt
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
19
|
||||
0 1 2 4294967295 6 1
|
||||
0 2 4 0 8 2
|
||||
0 4 9 1 12 3
|
||||
0 9 12 2 17 5
|
||||
0 11 10 5 18 4294967295
|
||||
0 12 11 3 18 4
|
||||
1 3 2 7 8 0
|
||||
1 8 3 4294967295 11 6
|
||||
2 3 4 6 10 1
|
||||
3 5 6 11 13 10
|
||||
3 6 4 9 12 8
|
||||
3 8 5 7 14 9
|
||||
4 6 9 10 15 2
|
||||
5 7 6 14 15 9
|
||||
5 8 7 11 16 13
|
||||
6 7 9 13 16 12
|
||||
7 8 9 14 4294967295 15
|
||||
9 10 12 4294967295 18 3
|
||||
10 11 12 4 5 17
|
||||
|
||||
9
|
||||
0 1
|
||||
0 9
|
||||
1 2
|
||||
2 3
|
||||
3 5
|
||||
5 6
|
||||
6 7
|
||||
7 8
|
||||
8 9
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
43
include/CDT/tests/expected/Hanging2__auto_resolve_all.txt
Normal file
43
include/CDT/tests/expected/Hanging2__auto_resolve_all.txt
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
27
|
||||
0 1 11 4294967295 5 3
|
||||
0 3 2 2 6 4294967295
|
||||
0 4 3 3 8 1
|
||||
0 11 4 0 15 2
|
||||
1 2 12 4294967295 7 5
|
||||
1 12 11 4 24 0
|
||||
2 3 13 1 12 7
|
||||
2 13 12 6 25 4
|
||||
3 4 5 2 14 9
|
||||
3 5 7 8 16 10
|
||||
3 7 12 9 20 11
|
||||
3 12 15 10 25 13
|
||||
3 14 13 13 26 6
|
||||
3 15 14 11 26 12
|
||||
4 6 5 15 16 8
|
||||
4 11 6 3 19 14
|
||||
5 6 7 14 18 9
|
||||
6 8 9 19 21 18
|
||||
6 9 7 17 20 16
|
||||
6 11 8 15 22 17
|
||||
7 9 12 18 23 10
|
||||
8 10 9 22 23 17
|
||||
8 11 10 19 24 21
|
||||
9 10 12 21 24 20
|
||||
10 11 12 22 5 23
|
||||
12 13 15 7 26 11
|
||||
13 14 15 12 13 25
|
||||
|
||||
9
|
||||
3 4
|
||||
3 12
|
||||
4 5
|
||||
5 6
|
||||
6 8
|
||||
8 9
|
||||
9 10
|
||||
10 11
|
||||
11 12
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
25
include/CDT/tests/expected/Hanging2__auto_resolve_auto.txt
Normal file
25
include/CDT/tests/expected/Hanging2__auto_resolve_auto.txt
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
9
|
||||
0 1 2 4294967295 4294967295 1
|
||||
0 2 4 0 3 2
|
||||
0 4 9 1 6 4294967295
|
||||
2 3 4 4294967295 5 1
|
||||
3 5 6 4294967295 4294967295 5
|
||||
3 6 4 4 6 3
|
||||
4 6 9 5 7 2
|
||||
6 7 9 4294967295 8 6
|
||||
7 8 9 4294967295 4294967295 7
|
||||
|
||||
9
|
||||
0 1
|
||||
0 9
|
||||
1 2
|
||||
2 3
|
||||
3 5
|
||||
5 6
|
||||
6 7
|
||||
7 8
|
||||
8 9
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
25
include/CDT/tests/expected/Hanging2__auto_resolve_outer.txt
Normal file
25
include/CDT/tests/expected/Hanging2__auto_resolve_outer.txt
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
9
|
||||
0 1 2 4294967295 4294967295 1
|
||||
0 2 4 0 3 2
|
||||
0 4 9 1 6 4294967295
|
||||
2 3 4 4294967295 5 1
|
||||
3 5 6 4294967295 4294967295 5
|
||||
3 6 4 4 6 3
|
||||
4 6 9 5 7 2
|
||||
6 7 9 4294967295 8 6
|
||||
7 8 9 4294967295 4294967295 7
|
||||
|
||||
9
|
||||
0 1
|
||||
0 9
|
||||
1 2
|
||||
2 3
|
||||
3 5
|
||||
5 6
|
||||
6 7
|
||||
7 8
|
||||
8 9
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
35
include/CDT/tests/expected/Hanging2__auto_resolve_super.txt
Normal file
35
include/CDT/tests/expected/Hanging2__auto_resolve_super.txt
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
19
|
||||
0 1 2 4294967295 6 1
|
||||
0 2 4 0 8 2
|
||||
0 4 9 1 12 3
|
||||
0 9 12 2 17 5
|
||||
0 11 10 5 18 4294967295
|
||||
0 12 11 3 18 4
|
||||
1 3 2 7 8 0
|
||||
1 8 3 4294967295 11 6
|
||||
2 3 4 6 10 1
|
||||
3 5 6 11 13 10
|
||||
3 6 4 9 12 8
|
||||
3 8 5 7 14 9
|
||||
4 6 9 10 15 2
|
||||
5 7 6 14 15 9
|
||||
5 8 7 11 16 13
|
||||
6 7 9 13 16 12
|
||||
7 8 9 14 4294967295 15
|
||||
9 10 12 4294967295 18 3
|
||||
10 11 12 4 5 17
|
||||
|
||||
9
|
||||
0 1
|
||||
0 9
|
||||
1 2
|
||||
2 3
|
||||
3 5
|
||||
5 6
|
||||
6 7
|
||||
7 8
|
||||
8 9
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
17
|
||||
0 1 2 4294967295 4294967295 1
|
||||
0 2 16 0 2 4294967295
|
||||
2 13 16 4294967295 15 1
|
||||
3 4 18 7 8 6
|
||||
3 5 6 4294967295 4294967295 5
|
||||
3 6 20 4 11 7
|
||||
3 18 13 3 16 4294967295
|
||||
3 20 4 5 9 3
|
||||
4 15 18 9 4294967295 3
|
||||
4 20 15 7 4294967295 8
|
||||
6 7 19 4294967295 12 11
|
||||
6 19 20 10 4294967295 5
|
||||
7 9 19 13 4294967295 10
|
||||
7 14 9 4294967295 14 12
|
||||
8 9 14 4294967295 13 4294967295
|
||||
13 17 16 16 4294967295 2
|
||||
13 18 17 6 4294967295 15
|
||||
|
||||
17
|
||||
0 1
|
||||
0 16
|
||||
1 2
|
||||
2 13
|
||||
3 5
|
||||
3 13
|
||||
5 6
|
||||
6 7
|
||||
7 14
|
||||
8 9
|
||||
8 14
|
||||
9 19
|
||||
15 18
|
||||
15 20
|
||||
16 17
|
||||
17 18
|
||||
19 20
|
||||
|
||||
0
|
||||
|
||||
11
|
||||
0 16
|
||||
1
|
||||
0 9
|
||||
2 13
|
||||
1
|
||||
2 3
|
||||
3 13
|
||||
1
|
||||
2 3
|
||||
7 14
|
||||
1
|
||||
7 8
|
||||
8 14
|
||||
1
|
||||
7 8
|
||||
9 19
|
||||
1
|
||||
0 9
|
||||
15 18
|
||||
1
|
||||
0 9
|
||||
15 20
|
||||
1
|
||||
0 9
|
||||
16 17
|
||||
1
|
||||
0 9
|
||||
17 18
|
||||
1
|
||||
0 9
|
||||
19 20
|
||||
1
|
||||
0 9
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
17
|
||||
0 1 6 4294967295 5 3
|
||||
0 3 2 2 7 4294967295
|
||||
0 4 3 3 9 1
|
||||
0 6 4 0 12 2
|
||||
1 2 8 4294967295 8 6
|
||||
1 7 6 6 14 0
|
||||
1 8 7 4 15 5
|
||||
2 3 9 1 10 8
|
||||
2 9 8 7 16 4
|
||||
3 4 10 2 12 11
|
||||
3 5 9 11 13 7
|
||||
3 10 5 9 13 10
|
||||
4 6 10 3 14 9
|
||||
5 10 9 11 16 10
|
||||
6 7 10 5 15 12
|
||||
7 8 10 6 16 14
|
||||
8 9 10 8 13 15
|
||||
|
||||
4
|
||||
3 10
|
||||
6 10
|
||||
7 10
|
||||
8 10
|
||||
|
||||
0
|
||||
|
||||
4
|
||||
3 10
|
||||
1
|
||||
3 7
|
||||
6 10
|
||||
1
|
||||
6 8
|
||||
7 10
|
||||
1
|
||||
3 7
|
||||
8 10
|
||||
1
|
||||
6 8
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
15
|
||||
0 1 7 4294967295 6 4
|
||||
0 3 2 2 7 4294967295
|
||||
0 4 3 3 9 1
|
||||
0 6 4 4 12 2
|
||||
0 7 6 0 12 3
|
||||
1 2 8 4294967295 8 6
|
||||
1 8 7 5 14 0
|
||||
2 3 9 1 10 8
|
||||
2 9 8 7 14 5
|
||||
3 4 7 2 12 11
|
||||
3 5 9 11 13 7
|
||||
3 7 5 9 13 10
|
||||
4 6 7 3 4 9
|
||||
5 7 9 11 14 10
|
||||
7 8 9 6 8 13
|
||||
|
||||
1
|
||||
3 7
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
0
|
||||
|
||||
1
|
||||
0 4
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
0
|
||||
|
||||
1
|
||||
0 4
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
6
|
||||
0 1 4 4294967295 3 2
|
||||
0 2 6 2 4 4294967295
|
||||
0 4 2 0 4 1
|
||||
1 3 4 4294967295 4294967295 0
|
||||
2 4 6 2 5 1
|
||||
4 5 6 4294967295 4294967295 4
|
||||
|
||||
1
|
||||
0 4
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
15
|
||||
0 1 7 4294967295 6 4
|
||||
0 3 2 2 7 4294967295
|
||||
0 4 3 3 9 1
|
||||
0 6 4 4 12 2
|
||||
0 7 6 0 12 3
|
||||
1 2 8 4294967295 8 6
|
||||
1 8 7 5 14 0
|
||||
2 3 9 1 10 8
|
||||
2 9 8 7 14 5
|
||||
3 4 7 2 12 11
|
||||
3 5 9 11 13 7
|
||||
3 7 5 9 13 10
|
||||
4 6 7 3 4 9
|
||||
5 7 9 11 14 10
|
||||
7 8 9 6 8 13
|
||||
|
||||
1
|
||||
3 7
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
0
|
||||
|
||||
1
|
||||
0 4
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
0
|
||||
|
||||
1
|
||||
0 4
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
6
|
||||
0 1 4 4294967295 3 2
|
||||
0 2 6 2 4 4294967295
|
||||
0 4 2 0 4 1
|
||||
1 3 4 4294967295 4294967295 0
|
||||
2 4 6 2 5 1
|
||||
4 5 6 4294967295 4294967295 4
|
||||
|
||||
1
|
||||
0 4
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
23
include/CDT/tests/expected/Hanging__auto_ignore_all.txt
Normal file
23
include/CDT/tests/expected/Hanging__auto_ignore_all.txt
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
15
|
||||
0 1 6 4294967295 5 3
|
||||
0 3 2 2 7 4294967295
|
||||
0 4 3 3 9 1
|
||||
0 6 4 0 12 2
|
||||
1 2 8 4294967295 8 6
|
||||
1 7 6 6 12 0
|
||||
1 8 7 4 14 5
|
||||
2 3 9 1 10 8
|
||||
2 9 8 7 14 4
|
||||
3 4 7 2 12 11
|
||||
3 5 9 11 13 7
|
||||
3 7 5 9 13 10
|
||||
4 6 7 3 5 9
|
||||
5 7 9 11 14 10
|
||||
7 8 9 6 8 13
|
||||
|
||||
1
|
||||
3 7
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
8
include/CDT/tests/expected/Hanging__auto_ignore_auto.txt
Normal file
8
include/CDT/tests/expected/Hanging__auto_ignore_auto.txt
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
0
|
||||
|
||||
1
|
||||
0 4
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
0
|
||||
|
||||
1
|
||||
0 4
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
14
include/CDT/tests/expected/Hanging__auto_ignore_super.txt
Normal file
14
include/CDT/tests/expected/Hanging__auto_ignore_super.txt
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
6
|
||||
0 1 4 4294967295 3 2
|
||||
0 2 6 2 4 4294967295
|
||||
0 4 2 0 4 1
|
||||
1 3 4 4294967295 4294967295 0
|
||||
2 4 6 2 5 1
|
||||
4 5 6 4294967295 4294967295 4
|
||||
|
||||
1
|
||||
0 4
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
23
include/CDT/tests/expected/Hanging__auto_resolve_all.txt
Normal file
23
include/CDT/tests/expected/Hanging__auto_resolve_all.txt
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
15
|
||||
0 1 6 4294967295 5 3
|
||||
0 3 2 2 7 4294967295
|
||||
0 4 3 3 9 1
|
||||
0 6 4 0 12 2
|
||||
1 2 8 4294967295 8 6
|
||||
1 7 6 6 12 0
|
||||
1 8 7 4 14 5
|
||||
2 3 9 1 10 8
|
||||
2 9 8 7 14 4
|
||||
3 4 7 2 12 11
|
||||
3 5 9 11 13 7
|
||||
3 7 5 9 13 10
|
||||
4 6 7 3 5 9
|
||||
5 7 9 11 14 10
|
||||
7 8 9 6 8 13
|
||||
|
||||
1
|
||||
3 7
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
0
|
||||
|
||||
1
|
||||
0 4
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
0
|
||||
|
||||
1
|
||||
0 4
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
14
include/CDT/tests/expected/Hanging__auto_resolve_super.txt
Normal file
14
include/CDT/tests/expected/Hanging__auto_resolve_super.txt
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
6
|
||||
0 1 4 4294967295 3 2
|
||||
0 2 6 2 4 4294967295
|
||||
0 4 2 0 4 1
|
||||
1 3 4 4294967295 4294967295 0
|
||||
2 4 6 2 5 1
|
||||
4 5 6 4294967295 4294967295 4
|
||||
|
||||
1
|
||||
0 4
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
17
|
||||
0 1 4 4294967295 5 2
|
||||
0 3 10 2 11 3
|
||||
0 4 3 0 9 1
|
||||
0 10 2 1 8 4294967295
|
||||
1 2 9 4294967295 8 7
|
||||
1 5 4 6 12 0
|
||||
1 8 5 7 14 5
|
||||
1 9 8 4 15 6
|
||||
2 10 9 3 16 4
|
||||
3 4 6 2 12 10
|
||||
3 6 7 9 13 11
|
||||
3 7 10 10 16 1
|
||||
4 5 6 5 13 9
|
||||
5 7 6 14 10 12
|
||||
5 8 7 6 15 13
|
||||
7 8 9 14 7 16
|
||||
7 9 10 15 8 11
|
||||
|
||||
8
|
||||
3 4
|
||||
3 10
|
||||
4 5
|
||||
5 6
|
||||
6 7
|
||||
7 8
|
||||
8 9
|
||||
9 10
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
6
|
||||
0 1 3 4294967295 3 1
|
||||
0 3 4 0 4294967295 2
|
||||
0 4 7 1 5 4294967295
|
||||
1 2 3 4294967295 4294967295 0
|
||||
4 5 6 4294967295 4294967295 5
|
||||
4 6 7 4 4294967295 2
|
||||
|
||||
8
|
||||
0 1
|
||||
0 7
|
||||
1 2
|
||||
2 3
|
||||
3 4
|
||||
4 5
|
||||
5 6
|
||||
6 7
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
6
|
||||
0 1 3 4294967295 3 1
|
||||
0 3 4 0 4294967295 2
|
||||
0 4 7 1 5 4294967295
|
||||
1 2 3 4294967295 4294967295 0
|
||||
4 5 6 4294967295 4294967295 5
|
||||
4 6 7 4 4294967295 2
|
||||
|
||||
8
|
||||
0 1
|
||||
0 7
|
||||
1 2
|
||||
2 3
|
||||
3 4
|
||||
4 5
|
||||
5 6
|
||||
6 7
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
8
|
||||
0 1 3 4294967295 3 1
|
||||
0 3 4 0 4 2
|
||||
0 4 7 1 7 4294967295
|
||||
1 2 3 4294967295 4 0
|
||||
2 4 3 5 1 3
|
||||
2 5 4 4294967295 6 4
|
||||
4 5 6 5 4294967295 7
|
||||
4 6 7 6 4294967295 2
|
||||
|
||||
8
|
||||
0 1
|
||||
0 7
|
||||
1 2
|
||||
2 3
|
||||
3 4
|
||||
4 5
|
||||
5 6
|
||||
6 7
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
17
|
||||
0 1 4 4294967295 5 2
|
||||
0 3 10 2 11 3
|
||||
0 4 3 0 9 1
|
||||
0 10 2 1 8 4294967295
|
||||
1 2 9 4294967295 8 7
|
||||
1 5 4 6 12 0
|
||||
1 8 5 7 14 5
|
||||
1 9 8 4 15 6
|
||||
2 10 9 3 16 4
|
||||
3 4 6 2 12 10
|
||||
3 6 7 9 13 11
|
||||
3 7 10 10 16 1
|
||||
4 5 6 5 13 9
|
||||
5 7 6 14 10 12
|
||||
5 8 7 6 15 13
|
||||
7 8 9 14 7 16
|
||||
7 9 10 15 8 11
|
||||
|
||||
8
|
||||
3 4
|
||||
3 10
|
||||
4 5
|
||||
5 6
|
||||
6 7
|
||||
7 8
|
||||
8 9
|
||||
9 10
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
6
|
||||
0 1 3 4294967295 3 1
|
||||
0 3 4 0 4294967295 2
|
||||
0 4 7 1 5 4294967295
|
||||
1 2 3 4294967295 4294967295 0
|
||||
4 5 6 4294967295 4294967295 5
|
||||
4 6 7 4 4294967295 2
|
||||
|
||||
8
|
||||
0 1
|
||||
0 7
|
||||
1 2
|
||||
2 3
|
||||
3 4
|
||||
4 5
|
||||
5 6
|
||||
6 7
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
6
|
||||
0 1 3 4294967295 3 1
|
||||
0 3 4 0 4294967295 2
|
||||
0 4 7 1 5 4294967295
|
||||
1 2 3 4294967295 4294967295 0
|
||||
4 5 6 4294967295 4294967295 5
|
||||
4 6 7 4 4294967295 2
|
||||
|
||||
8
|
||||
0 1
|
||||
0 7
|
||||
1 2
|
||||
2 3
|
||||
3 4
|
||||
4 5
|
||||
5 6
|
||||
6 7
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
8
|
||||
0 1 3 4294967295 3 1
|
||||
0 3 4 0 4 2
|
||||
0 4 7 1 7 4294967295
|
||||
1 2 3 4294967295 4 0
|
||||
2 4 3 5 1 3
|
||||
2 5 4 4294967295 6 4
|
||||
4 5 6 5 4294967295 7
|
||||
4 6 7 6 4294967295 2
|
||||
|
||||
8
|
||||
0 1
|
||||
0 7
|
||||
1 2
|
||||
2 3
|
||||
3 4
|
||||
4 5
|
||||
5 6
|
||||
6 7
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
32
include/CDT/tests/expected/Letter u__auto_ignore_all.txt
Normal file
32
include/CDT/tests/expected/Letter u__auto_ignore_all.txt
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
17
|
||||
0 1 3 4294967295 4 1
|
||||
0 3 10 0 10 2
|
||||
0 10 2 1 8 4294967295
|
||||
1 2 9 4294967295 8 7
|
||||
1 4 3 5 9 0
|
||||
1 5 4 6 11 4
|
||||
1 8 5 7 12 5
|
||||
1 9 8 3 15 6
|
||||
2 10 9 2 16 3
|
||||
3 4 6 4 11 10
|
||||
3 6 10 9 13 1
|
||||
4 5 6 5 12 9
|
||||
5 8 6 6 14 11
|
||||
6 7 10 14 16 10
|
||||
6 8 7 12 15 13
|
||||
7 8 9 14 7 16
|
||||
7 9 10 15 8 13
|
||||
|
||||
8
|
||||
3 4
|
||||
3 10
|
||||
4 5
|
||||
5 6
|
||||
6 7
|
||||
7 8
|
||||
8 9
|
||||
9 10
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
21
include/CDT/tests/expected/Letter u__auto_ignore_auto.txt
Normal file
21
include/CDT/tests/expected/Letter u__auto_ignore_auto.txt
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
6
|
||||
0 1 3 4294967295 2 1
|
||||
0 3 7 0 3 4294967295
|
||||
1 2 3 4294967295 4294967295 0
|
||||
3 4 7 4294967295 5 1
|
||||
4 5 6 4294967295 4294967295 5
|
||||
4 6 7 4 4294967295 3
|
||||
|
||||
8
|
||||
0 1
|
||||
0 7
|
||||
1 2
|
||||
2 3
|
||||
3 4
|
||||
4 5
|
||||
5 6
|
||||
6 7
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
21
include/CDT/tests/expected/Letter u__auto_ignore_outer.txt
Normal file
21
include/CDT/tests/expected/Letter u__auto_ignore_outer.txt
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
6
|
||||
0 1 3 4294967295 2 1
|
||||
0 3 7 0 3 4294967295
|
||||
1 2 3 4294967295 4294967295 0
|
||||
3 4 7 4294967295 5 1
|
||||
4 5 6 4294967295 4294967295 5
|
||||
4 6 7 4 4294967295 3
|
||||
|
||||
8
|
||||
0 1
|
||||
0 7
|
||||
1 2
|
||||
2 3
|
||||
3 4
|
||||
4 5
|
||||
5 6
|
||||
6 7
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
23
include/CDT/tests/expected/Letter u__auto_ignore_super.txt
Normal file
23
include/CDT/tests/expected/Letter u__auto_ignore_super.txt
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
8
|
||||
0 1 3 4294967295 2 1
|
||||
0 3 7 0 4 4294967295
|
||||
1 2 3 4294967295 3 0
|
||||
2 5 3 4294967295 5 2
|
||||
3 4 7 5 7 1
|
||||
3 5 4 3 6 4
|
||||
4 5 6 5 4294967295 7
|
||||
4 6 7 6 4294967295 4
|
||||
|
||||
8
|
||||
0 1
|
||||
0 7
|
||||
1 2
|
||||
2 3
|
||||
3 4
|
||||
4 5
|
||||
5 6
|
||||
6 7
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
32
include/CDT/tests/expected/Letter u__auto_resolve_all.txt
Normal file
32
include/CDT/tests/expected/Letter u__auto_resolve_all.txt
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
17
|
||||
0 1 3 4294967295 4 1
|
||||
0 3 10 0 10 2
|
||||
0 10 2 1 8 4294967295
|
||||
1 2 9 4294967295 8 7
|
||||
1 4 3 5 9 0
|
||||
1 5 4 6 11 4
|
||||
1 8 5 7 12 5
|
||||
1 9 8 3 15 6
|
||||
2 10 9 2 16 3
|
||||
3 4 6 4 11 10
|
||||
3 6 10 9 13 1
|
||||
4 5 6 5 12 9
|
||||
5 8 6 6 14 11
|
||||
6 7 10 14 16 10
|
||||
6 8 7 12 15 13
|
||||
7 8 9 14 7 16
|
||||
7 9 10 15 8 13
|
||||
|
||||
8
|
||||
3 4
|
||||
3 10
|
||||
4 5
|
||||
5 6
|
||||
6 7
|
||||
7 8
|
||||
8 9
|
||||
9 10
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
21
include/CDT/tests/expected/Letter u__auto_resolve_auto.txt
Normal file
21
include/CDT/tests/expected/Letter u__auto_resolve_auto.txt
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
6
|
||||
0 1 3 4294967295 2 1
|
||||
0 3 7 0 3 4294967295
|
||||
1 2 3 4294967295 4294967295 0
|
||||
3 4 7 4294967295 5 1
|
||||
4 5 6 4294967295 4294967295 5
|
||||
4 6 7 4 4294967295 3
|
||||
|
||||
8
|
||||
0 1
|
||||
0 7
|
||||
1 2
|
||||
2 3
|
||||
3 4
|
||||
4 5
|
||||
5 6
|
||||
6 7
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
21
include/CDT/tests/expected/Letter u__auto_resolve_outer.txt
Normal file
21
include/CDT/tests/expected/Letter u__auto_resolve_outer.txt
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
6
|
||||
0 1 3 4294967295 2 1
|
||||
0 3 7 0 3 4294967295
|
||||
1 2 3 4294967295 4294967295 0
|
||||
3 4 7 4294967295 5 1
|
||||
4 5 6 4294967295 4294967295 5
|
||||
4 6 7 4 4294967295 3
|
||||
|
||||
8
|
||||
0 1
|
||||
0 7
|
||||
1 2
|
||||
2 3
|
||||
3 4
|
||||
4 5
|
||||
5 6
|
||||
6 7
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
23
include/CDT/tests/expected/Letter u__auto_resolve_super.txt
Normal file
23
include/CDT/tests/expected/Letter u__auto_resolve_super.txt
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
8
|
||||
0 1 3 4294967295 2 1
|
||||
0 3 7 0 4 4294967295
|
||||
1 2 3 4294967295 3 0
|
||||
2 5 3 4294967295 5 2
|
||||
3 4 7 5 7 1
|
||||
3 5 4 3 6 4
|
||||
4 5 6 5 4294967295 7
|
||||
4 6 7 6 4294967295 4
|
||||
|
||||
8
|
||||
0 1
|
||||
0 7
|
||||
1 2
|
||||
2 3
|
||||
3 4
|
||||
4 5
|
||||
5 6
|
||||
6 7
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
41
|
||||
0 1 4 4294967295 5 2
|
||||
0 3 6 2 8 3
|
||||
0 4 3 0 7 1
|
||||
0 6 2 1 6 4294967295
|
||||
1 2 5 4294967295 6 5
|
||||
1 5 4 4 9 0
|
||||
2 6 5 3 16 4
|
||||
3 4 14 2 10 8
|
||||
3 14 6 7 20 1
|
||||
4 5 13 5 16 13
|
||||
4 7 14 14 20 7
|
||||
4 8 15 12 21 14
|
||||
4 9 8 15 18 11
|
||||
4 13 18 9 36 15
|
||||
4 15 7 11 17 10
|
||||
4 18 9 13 24 12
|
||||
5 6 13 6 22 9
|
||||
6 7 15 20 14 21
|
||||
6 8 9 21 12 19
|
||||
6 9 22 18 23 22
|
||||
6 14 7 8 10 17
|
||||
6 15 8 17 11 18
|
||||
6 22 13 19 37 16
|
||||
9 10 22 24 25 19
|
||||
9 18 10 15 26 23
|
||||
10 11 22 27 31 23
|
||||
10 18 19 24 38 27
|
||||
10 19 11 26 29 25
|
||||
11 16 21 30 35 31
|
||||
11 19 20 27 39 30
|
||||
11 20 16 29 32 28
|
||||
11 21 22 28 40 25
|
||||
12 16 20 35 30 34
|
||||
12 17 21 34 40 35
|
||||
12 20 17 32 39 33
|
||||
12 21 16 33 28 32
|
||||
13 17 18 37 38 13
|
||||
13 22 17 22 40 36
|
||||
17 19 18 39 26 36
|
||||
17 20 19 34 29 38
|
||||
17 22 21 37 31 33
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
0
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
0
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
34
|
||||
0 1 11 4294967295 3 1
|
||||
0 11 3 0 13 4294967295
|
||||
1 2 10 4294967295 9 6
|
||||
1 4 11 7 13 0
|
||||
1 5 12 5 14 7
|
||||
1 6 5 8 11 4
|
||||
1 10 15 2 29 8
|
||||
1 12 4 4 10 3
|
||||
1 15 6 6 17 5
|
||||
2 3 10 4294967295 15 2
|
||||
3 4 12 13 7 14
|
||||
3 5 6 14 5 12
|
||||
3 6 19 11 16 15
|
||||
3 11 4 1 3 10
|
||||
3 12 5 10 4 11
|
||||
3 19 10 12 30 9
|
||||
6 7 19 17 18 12
|
||||
6 15 7 8 19 16
|
||||
7 8 19 20 24 16
|
||||
7 15 16 17 31 20
|
||||
7 16 8 19 22 18
|
||||
8 13 18 23 28 24
|
||||
8 16 17 20 32 23
|
||||
8 17 13 22 25 21
|
||||
8 18 19 21 33 18
|
||||
9 13 17 28 23 27
|
||||
9 14 18 27 33 28
|
||||
9 17 14 25 32 26
|
||||
9 18 13 26 21 25
|
||||
10 14 15 30 31 6
|
||||
10 19 14 15 33 29
|
||||
14 16 15 32 19 29
|
||||
14 17 16 27 22 31
|
||||
14 19 18 30 24 26
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
41
|
||||
0 1 4 4294967295 5 2
|
||||
0 3 6 2 8 3
|
||||
0 4 3 0 7 1
|
||||
0 6 2 1 6 4294967295
|
||||
1 2 5 4294967295 6 5
|
||||
1 5 4 4 9 0
|
||||
2 6 5 3 16 4
|
||||
3 4 14 2 10 8
|
||||
3 14 6 7 20 1
|
||||
4 5 13 5 16 13
|
||||
4 7 14 14 20 7
|
||||
4 8 15 12 21 14
|
||||
4 9 8 15 18 11
|
||||
4 13 18 9 36 15
|
||||
4 15 7 11 17 10
|
||||
4 18 9 13 24 12
|
||||
5 6 13 6 22 9
|
||||
6 7 15 20 14 21
|
||||
6 8 9 21 12 19
|
||||
6 9 22 18 23 22
|
||||
6 14 7 8 10 17
|
||||
6 15 8 17 11 18
|
||||
6 22 13 19 37 16
|
||||
9 10 22 24 25 19
|
||||
9 18 10 15 26 23
|
||||
10 11 22 27 31 23
|
||||
10 18 19 24 38 27
|
||||
10 19 11 26 29 25
|
||||
11 16 21 30 35 31
|
||||
11 19 20 27 39 30
|
||||
11 20 16 29 32 28
|
||||
11 21 22 28 40 25
|
||||
12 16 20 35 30 34
|
||||
12 17 21 34 40 35
|
||||
12 20 17 32 39 33
|
||||
12 21 16 33 28 32
|
||||
13 17 18 37 38 13
|
||||
13 22 17 22 40 36
|
||||
17 19 18 39 26 36
|
||||
17 20 19 34 29 38
|
||||
17 22 21 37 31 33
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
0
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
|
||||
0
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue