Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v1.3.0取り込み #4

Merged
merged 98 commits into from
Nov 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
98 commits
Select commit Hold shift + click to select a range
4057a50
Fixed a significant bug in Clipper.Engine.cs (C# only) (#470).
AngusJohnson Mar 28, 2023
0913ad9
Remove unused references across C# (#472)
philstopford Mar 29, 2023
e012779
Fixed a bug in ExecuteRectClipLines() (C++ only) (#471)
AngusJohnson Apr 2, 2023
0ce6056
perf: remove copy in offset (#481)
cwangbh Apr 3, 2023
1eab252
Minor tweak to StripDuplicates function (C++) (#481)
AngusJohnson Apr 3, 2023
3233b2a
Add googlebenchmark and improve the stripduplicates (#483)
cwangbh Apr 4, 2023
c898b4b
Changed default param in SimplifyPaths function **caution** (#485)
AngusJohnson Apr 8, 2023
1b86265
Update README.md
AngusJohnson Apr 8, 2023
cda99ed
Clipper.Engine
AngusJohnson Apr 22, 2023
d18faa9
fixed signifcant clipping bug (#500)
AngusJohnson Apr 23, 2023
95edbf6
Added ReuseableDataContainer64 class (Discuss. #491)
AngusJohnson May 1, 2023
6e15ba0
ClipperOffset
AngusJohnson May 16, 2023
117f885
Updated CI tests
AngusJohnson May 16, 2023
f2331c4
Minor tweak to PolyTree path ownership
AngusJohnson May 16, 2023
41fc758
Further tweaks to Polytree path ownership
AngusJohnson May 16, 2023
f3fd560
one more tweak to Polytree path ownership
AngusJohnson May 16, 2023
9d50a82
Fixed a minor (C++) bug in open path clipping when using Z (#525)
AngusJohnson May 20, 2023
3305b61
Update Clipper.Offset.cs (#537)
philstopford May 24, 2023
6d69b97
Renamed (again) ExecuteRectClip and ExecuteRectClipLines functions
AngusJohnson May 26, 2023
5aad319
Update clipper.engine.h, missing ` #include <stdint.h>` (#541)
loumalouomega May 27, 2023
9d946d7
Removed ConvexOnly parameter from ClipRect function (#542)
AngusJohnson May 29, 2023
e6d2ac1
Fixed infinite loop bug in C# code (#550).
AngusJohnson Jun 17, 2023
c49dd94
Use new keyword for hiding base class method (#552)
freza-tm Jun 17, 2023
81b01d2
Remove unused convex_only parameter from export rectclip functions (…
Gornhoth Jun 19, 2023
5f1699d
Minor improvement to the segment intersection algorithm (#568)
AngusJohnson Jul 16, 2023
562ef2d
Another minor bugfix in GetIntersectPoint(). (#568)
AngusJohnson Jul 17, 2023
866e402
Further fixes to Polytree nesting (#590)
AngusJohnson Jul 19, 2023
959f96e
Temporarily disabled Polytree unit testing. (Still buggy)
AngusJohnson Jul 19, 2023
015d5e7
Fix problem that may appear when including Windows.h before clipper h…
reunanen Jul 26, 2023
3867aab
Fixed several bugs in Polytree generation (#590, #600, #607)
AngusJohnson Aug 4, 2023
6222af4
Fixed a minor bug in RectClip (#597)
AngusJohnson Aug 6, 2023
739f2e3
Minor bugfix in polygon offsetting (#593)
AngusJohnson Aug 6, 2023
4ef91e9
Update README.md
AngusJohnson Aug 14, 2023
7cf615c
Another fix to a persistent bug in polytree nesting (#618)
AngusJohnson Aug 27, 2023
ba8e8a2
Fixed another Polytree nesting bug (C# only) //#638
AngusJohnson Sep 3, 2023
13bf2aa
Fixed a bug in RectClip (#637)
AngusJohnson Sep 8, 2023
e6e2201
Fixed a bug when offsetting a single point path (#617)
AngusJohnson Sep 9, 2023
388041f
Fixed a minor bug in ClipperOffset (#593)
AngusJohnson Sep 16, 2023
83b0ccc
Fixed bug in 180deg rounding (C++ & c#) //#593
AngusJohnson Sep 18, 2023
0b4da7e
Removed redundant GetIntersectPt function //#568
AngusJohnson Sep 18, 2023
0983504
When testing if a group is smaller than the offset (and thus will van…
SebastianDirks Sep 18, 2023
df61525
Improved testing for excessive offset shrinking //#651
AngusJohnson Sep 18, 2023
f9a40f0
create snk for signing (#647)
lutz Sep 18, 2023
b444ed3
Improve reporting test failures: separately show the measured and the…
reunanen Sep 22, 2023
b462b5b
Added a new join type (JoinType::Bevel) for offsetting //#615
AngusJohnson Sep 24, 2023
dc3b90f
C# only: truncate intersection point coordinates instead of rounding,…
reunanen Oct 1, 2023
8a3484f
C# only: specify rounding modes explicitly, so that they match the (S…
reunanen Oct 1, 2023
99eaaf1
.net Standard 2.0 (#652)
lutz Oct 1, 2023
5dc364a
Minor code tidy (C# only)
AngusJohnson Oct 1, 2023
1e46e2b
netstandard2.0 (C#)
AngusJohnson Oct 1, 2023
b37c974
version 1.2.3
AngusJohnson Oct 1, 2023
c7a4829
Update Clipper.cs (#673)
philstopford Oct 3, 2023
763526b
Added CMake updated clipper.version.h file
AngusJohnson Oct 4, 2023
a6ffab2
Fix cyclic header file dependency (#677)
ZeronSix Oct 5, 2023
91bf3c6
Fixed a bug in polytree nesting (#679)
AngusJohnson Oct 6, 2023
6a7a401
Fixed a Delphi only bug in Polytree path ownership (#687)
AngusJohnson Oct 16, 2023
0b5bf2f
Fixed a very minor bug merging touching polygons (Dis.#690)
AngusJohnson Oct 19, 2023
9ffd077
Major rewrite of clipper.export.h
AngusJohnson Oct 24, 2023
11c97a1
Minor bugfix in clipper.export.h
AngusJohnson Oct 25, 2023
266a706
clipper.export.h compile error
AngusJohnson Oct 25, 2023
2310524
clipper.export.h minor code tidy
AngusJohnson Oct 25, 2023
ee5223f
Updated clipper.export.h again
AngusJohnson Oct 25, 2023
d56becd
Added a simple C# demo that uses a Clipper2 DLL
AngusJohnson Oct 26, 2023
615a18d
Updated Clipper2.DLL test applications
AngusJohnson Oct 27, 2023
0b0dd11
Updated DLL test app
AngusJohnson Oct 28, 2023
c5a0cda
Tidied up C# test app for Clipper2 DLL.
AngusJohnson Oct 29, 2023
5fda66d
Another tidy of CSharp_TestApp (Clipper2 DLL demo)
AngusJohnson Oct 29, 2023
8552910
clipper.export.h code tidy
AngusJohnson Oct 29, 2023
07be562
Forgot to update TestExportHeaders :)
AngusJohnson Oct 29, 2023
01a3555
Minor code tidy
AngusJohnson Oct 30, 2023
8650a7b
Create ReadMe.md
AngusJohnson Oct 31, 2023
ff03eac
Update README.md
AngusJohnson Oct 31, 2023
775ec62
Numerous minor bugfixes to ClipperOffset (#703)
AngusJohnson Nov 8, 2023
2c4626b
Correct of typo in code documentation :)
AngusJohnson Nov 9, 2023
36cf9f7
Revert "Correct of typo in code documentation :)"
AngusJohnson Nov 9, 2023
571cab3
Corrected a typo in code documentation
AngusJohnson Nov 9, 2023
4c43946
Update README.md
AngusJohnson Nov 14, 2023
249c440
Update README.md
AngusJohnson Nov 14, 2023
e600a23
Update README.md
AngusJohnson Nov 14, 2023
21e3db5
Update ReadMe.md
AngusJohnson Nov 14, 2023
ab39a5e
Update ReadMe.md
AngusJohnson Nov 14, 2023
028a2b0
Update ReadMe.md
AngusJohnson Nov 14, 2023
c3839ac
Offsetting open paths has changed delta (#707)
AngusJohnson Nov 15, 2023
2c775d6
Merge branch 'main' of https://ghp_k8EUbvrIwCiGEtc8baedaTNGLEY12m09TL…
AngusJohnson Nov 15, 2023
7a481e8
Fix simplification of open path (#714)
klauslh Nov 17, 2023
60cd293
Caution: Fixed SimplifyPaths function in C# with confusing parameters
AngusJohnson Nov 18, 2023
466efe7
Update ReadMe.md
AngusJohnson Nov 18, 2023
4955873
Fixed bug where offsetting would occasionally lose a path (#715)
AngusJohnson Nov 19, 2023
84d8012
Merge branch 'main' of https://ghp_k8EUbvrIwCiGEtc8baedaTNGLEY12m09TL…
AngusJohnson Nov 19, 2023
9299eb6
Caution: Clipper.ReverseSolution and Clipper.PreserveCollinear now me…
AngusJohnson Nov 22, 2023
906bc1d
ClipperOffset: fixed bug where rounding wasn't entirely accurate //#724
AngusJohnson Nov 25, 2023
88d0bc7
Additional minor bugfix to ClipperOffset (#724 & Disc.#726)
AngusJohnson Nov 26, 2023
ff85874
Version 1.2.4
AngusJohnson Nov 26, 2023
0a6a3ab
Fixed a typo and tweaked documentation
AngusJohnson Nov 26, 2023
41851ca
Version 1.3.0
AngusJohnson Nov 28, 2023
98db566
Fixed a minor syntax error tripping some C++ compilers
AngusJohnson Nov 28, 2023
4e3fc73
Merge tag 'Cliper2_1.3.0' into drecom/develop
Egliss Nov 29, 2023
2e68c81
Update namespace
Egliss Nov 30, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions CPP/BenchMark/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
cmake_minimum_required(VERSION 3.15)
project(Clipper2_benchmarks VERSION 1.0 LANGUAGES C CXX)

if(NOT DEFINED CMAKE_CXX_STANDARD OR CMAKE_CXX_STANDARD LESS 17)
set(CMAKE_CXX_STANDARD 17)
endif()
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

# fetch the google benchmark library
include(FetchContent)
set(BENCHMARK_ENABLE_GTEST_TESTS OFF)
set(BENCHMARK_ENABLE_TESTING OFF)
message("start fetching the googlebenchmark")
FetchContent_Declare(googlebenchmark
GIT_REPOSITORY https://github.com/google/benchmark.git
GIT_TAG v1.7.1
)

FetchContent_MakeAvailable(
googlebenchmark)
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
message("fetching is done")

set(benchmark_srcs
PointInPolygonBenchmark.cpp
StripDuplicateBenchmark.cpp
# more to add
)

# add each benchmark from the benchmark_srcs
foreach(benchmark ${benchmark_srcs})
get_filename_component(benchmark_target ${benchmark} NAME_WE)

message(STATUS "${PROJECT_NAME} add benchmark ${benchmark_target}")
add_executable(${benchmark_target} ${benchmark})
target_include_directories(${benchmark_target}
PUBLIC ../Clipper2Lib/include
PUBLIC ../Utils
)

target_link_libraries(${benchmark_target}
benchmark::benchmark
)
endforeach()
329 changes: 329 additions & 0 deletions CPP/BenchMark/PointInPolygonBenchmark.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,329 @@
#include "benchmark/benchmark.h"
#include "clipper2/clipper.h"
#include "CommonUtils.h"
#include <iostream>
#include <cstdlib>

using namespace Clipper2Lib;
using benchmark::State;

template <typename T>
inline PointInPolygonResult PIP1(const Point<T>& pt, const Path<T>& polygon)
{
int val = 0;
typename Path<T>::const_iterator cbegin = polygon.cbegin(), first = cbegin, curr, prev;
typename Path<T>::const_iterator cend = polygon.cend();

while (first != cend && first->y == pt.y) ++first;
if (first == cend) // not a proper polygon
return PointInPolygonResult::IsOutside;

bool is_above = first->y < pt.y, starting_above = is_above;
curr = first + 1;
while (true)
{
if (curr == cend)
{
if (cend == first || first == cbegin) break;
cend = first;
curr = cbegin;
}

if (is_above)
{
while (curr != cend && curr->y < pt.y) ++curr;
if (curr == cend) continue;
}
else
{
while (curr != cend && curr->y > pt.y) ++curr;
if (curr == cend) continue;
}

if (curr == cbegin)
prev = polygon.cend() - 1;
else
prev = curr - 1;

if (curr->y == pt.y)
{
if (curr->x == pt.x ||
(curr->y == prev->y &&
((pt.x < prev->x) != (pt.x < curr->x))))
return PointInPolygonResult::IsOn;
++curr;
if (curr == first) break;
continue;
}

if (pt.x < curr->x && pt.x < prev->x)
{
// we're only interested in edges crossing on the left
}
else if (pt.x > prev->x && pt.x > curr->x)
val = 1 - val; // toggle val
else
{
double d = CrossProduct(*prev, *curr, pt);
if (d == 0) return PointInPolygonResult::IsOn;
if ((d < 0) == is_above) val = 1 - val;
}
is_above = !is_above;
++curr;
}

if (is_above != starting_above)
{
cend = polygon.cend();
if (curr == cend) curr = cbegin;
if (curr == cbegin) prev = cend - 1;
else prev = curr - 1;
double d = CrossProduct(*prev, *curr, pt);
if (d == 0) return PointInPolygonResult::IsOn;
if ((d < 0) == is_above) val = 1 - val;
}

return (val == 0) ?
PointInPolygonResult::IsOutside :
PointInPolygonResult::IsInside;
}


template <typename T>
inline PointInPolygonResult PIP2(const Point<T>& pt, const Path<T>& polygon)
{
if (!polygon.size()) return PointInPolygonResult::IsOutside;
Path<T>::const_iterator cend = polygon.cend();
Path<T>::const_iterator prev = cend - 1;
Path<T>::const_iterator curr = polygon.cbegin();

bool is_above;
if (prev->y == pt.y)
{
if (pt == *prev) return PointInPolygonResult::IsOn;
if ((curr->y == pt.y) && ((curr->x == pt.x) ||
((pt.x > prev->x) == (pt.x < curr->x))))
return PointInPolygonResult::IsOn;
Path<T>::const_reverse_iterator pr = polygon.crbegin() +1;
while (pr != polygon.crend() && pr->y == pt.y) ++pr;
is_above = pr == polygon.crend() || pr->y < pt.y;
}
else is_above = prev->y < pt.y;

int val = 0;
while (curr != cend)
{
if (is_above)
{
while (curr != cend && curr->y < pt.y) { prev = curr; ++curr; }
if (curr == cend) break;
}
else
{
while (curr != cend && curr->y > pt.y) { prev = curr; ++curr; }
if (curr == cend) break;
}

if (curr->y == pt.y)
{
if ((curr->x == pt.x) || ((curr->y == prev->y) &&
((pt.x > prev->x) == (pt.x < curr->x))))
return PointInPolygonResult::IsOn;
prev = curr;
++curr;
continue;
}

if (pt.x < curr->x && pt.x < prev->x)
{
// we're only interested in edges crossing on the left
}
else if (pt.x > prev->x && pt.x > curr->x)
++val;
else
{
double d = CrossProduct(*prev, *curr, pt);
if (d == 0) return PointInPolygonResult::IsOn;
if ((d < 0) == is_above) ++val;
}
is_above = !is_above;
prev = curr;
++curr;
}

return (val % 2) ? PointInPolygonResult::IsInside : PointInPolygonResult::IsOutside;
}


// "Optimal Reliable Point-in-Polygon Test and
// Differential Coding Boolean Operations on Polygons"
// by Jianqiang Hao et al.
// Symmetry 2018, 10(10), 477; https://doi.org/10.3390/sym10100477
template <typename T>
static PointInPolygonResult PIP3(const Point<T> &pt, const Path<T> &path)
{
T x1, y1, x2, y2;
int k = 0;
Path<T>::const_iterator itPrev = path.cend() - 1;
Path<T>::const_iterator itCurr = path.cbegin();
for ( ; itCurr != path.cend(); ++itCurr)
{
y1 = itPrev->y - pt.y;
y2 = itCurr->y - pt.y;
if (((y1 < 0) && (y2 < 0)) || ((y1 > 0) && (y2 > 0)))
{
itPrev = itCurr;
continue;
}

x1 = itPrev->x - pt.x;
x2 = itCurr->x - pt.x;
if ((y1 <= 0) && (y2 > 0))
{
//double f = double(x1) * y2 - double(x2) * y1; // avoids int overflow
int64_t f = x1 * y2 - x2 * y1;
if (f > 0) ++k;
else if (f == 0) return PointInPolygonResult::IsOn;
}
else if ((y1 > 0) && (y2 <= 0))
{
int64_t f = x1 * y2 - x2 * y1;
if (f < 0) ++k;
else if (f == 0) return PointInPolygonResult::IsOn;
}
else if (((y2 == 0) && (y1 < 0)) || ((y1 == 0) && (y2 < 0)))
{
int64_t f = x1 * y2 - x2 * y1;
if (f == 0) return PointInPolygonResult::IsOn;
}
else if ((y1 == 0) && (y2 == 0) &&
(((x2 <= 0) && (x1 >= 0)) || ((x1 <= 0) && (x2 >= 0))))
return PointInPolygonResult::IsOn;
itPrev = itCurr;
}
if (k % 2) return PointInPolygonResult::IsInside;
return PointInPolygonResult::IsOutside;
}


Paths64 paths;
Point64 mp;
PointInPolygonResult pip1 = PointInPolygonResult::IsOn;
PointInPolygonResult pip2 = PointInPolygonResult::IsOn;
PointInPolygonResult pip3 = PointInPolygonResult::IsOn;


static void BM_PIP1(benchmark::State& state)
{
for (auto _ : state)
{
pip1 = PIP1(mp, paths[state.range(0)]);
}
}

static void BM_PIP2(benchmark::State& state)
{
for (auto _ : state)
{
pip2 = PIP2(mp, paths[state.range(0)]);
}
}

static void BM_PIP3(benchmark::State& state)
{
for (auto _ : state)
{
pip3 = PIP3(mp, paths[state.range(0)]);
}
}

static void CustomArguments(benchmark::internal::Benchmark* b)
{
for (int i = 0; i < paths.size(); ++i) b->Args({ i });
}

enum DoTests { do_stress_test_only, do_benchmark_only, do_all_tests };

int main(int argc, char** argv) {

const DoTests do_tests = do_all_tests;

if (do_tests != do_benchmark_only)
{
// stress test PIP2 with unusual polygons
mp = Point64(10, 10);
std::vector<PointInPolygonResult> pipResults;

paths.push_back({});
pipResults.push_back(PointInPolygonResult::IsOutside);
paths.push_back(MakePath({ 100,10, 200,10 }));
pipResults.push_back(PointInPolygonResult::IsOutside);
paths.push_back(MakePath({ 100,10, 200,10, 10,10, 20,20 }));
pipResults.push_back(PointInPolygonResult::IsOn);
paths.push_back(MakePath({ 10,10 }));
pipResults.push_back(PointInPolygonResult::IsOn);
paths.push_back(MakePath({ 100,10 }));
pipResults.push_back(PointInPolygonResult::IsOutside);
paths.push_back(MakePath({ 100,10, 110,20, 200,10, 10,10, 20,20 }));
pipResults.push_back(PointInPolygonResult::IsOn);
paths.push_back(MakePath({ 100,10, 110,20, 200,10, 20,20 }));
pipResults.push_back(PointInPolygonResult::IsOutside);
paths.push_back(MakePath({ 200,0, 0,0, 10,20, 200,0, 20,0 }));
pipResults.push_back(PointInPolygonResult::IsInside);
paths.push_back(MakePath({ 0,0, 20,20, 100,0 }));
pipResults.push_back(PointInPolygonResult::IsOn);

std::cout << "Stress testing PIP1 for errors: ";
for (size_t i = 0; i < paths.size(); ++i)
if (PIP1(mp, paths[i]) != pipResults[i])
std::cout << " (" << i << ")";
std::cout << std::endl;
std::cout << "Stress testing PIP2 for errors: ";
for (size_t i = 0; i < paths.size(); ++i)
if (PIP2(mp, paths[i]) != pipResults[i])
std::cout << " (" << i << ")";
std::cout << std::endl;
std::cout << "Stress testing PIP3 for errors: ";
for (size_t i = 0; i < paths.size(); ++i)
if (PIP3(mp, paths[i]) != pipResults[i])
std::cout << " (" << i << ")";
std::cout << std::endl << std::endl;

if (do_tests != do_all_tests)
{
std::string _;
std::getline(std::cin, _);
return 0;
}
}

if (do_tests == do_stress_test_only) return 0;

// compare 3 PIP algorithms
const int width = 600000, height = 400000;
mp = Point64(width / 2, height / 2);
paths.clear();
srand((unsigned)time(0));
for (int i = 0, count = 10000; i < 5; ++i, count *= 10)
paths.push_back(MakeRandomPoly(width, height, count));

benchmark::Initialize(&argc, argv);
BENCHMARK(BM_PIP1)->Apply(CustomArguments); // current Clipper2
BENCHMARK(BM_PIP2)->Apply(CustomArguments); // modified Clipper2
BENCHMARK(BM_PIP3)->Apply(CustomArguments); // Hao et al. (2018)
benchmark::RunSpecifiedBenchmarks();

if (pip2 != pip1 || pip3 != pip1)
{
if (pip2 != pip1)
std::cout << "PIP2 result is wrong!!!";
else
std::cout << "PIP3 result is wrong!!!";
std::cout << paths[2] << std::endl << std::endl;
std::string _;
std::getline(std::cin, _);
return 1;
}

return 0;
}
6 changes: 6 additions & 0 deletions CPP/BenchMark/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# google benchmark
this can be enabled by setting the option in the `CPP/CMakeLists.txt`

```cmake
option(USE_EXTERNAL_GBENCHMARK "Use the googlebenchmark" ON)
```
Loading