You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-18 14:21:41 +00:00
clipper2: Update to 1.5.2
This commit is contained in:
110
thirdparty/clipper2/src/clipper.engine.cpp
vendored
110
thirdparty/clipper2/src/clipper.engine.cpp
vendored
@@ -1,21 +1,15 @@
|
||||
/*******************************************************************************
|
||||
* Author : Angus Johnson *
|
||||
* Date : 27 April 2024 *
|
||||
* Website : http://www.angusj.com *
|
||||
* Date : 17 September 2024 *
|
||||
* Website : https://www.angusj.com *
|
||||
* Copyright : Angus Johnson 2010-2024 *
|
||||
* Purpose : This is the main polygon clipping module *
|
||||
* License : http://www.boost.org/LICENSE_1_0.txt *
|
||||
* License : https://www.boost.org/LICENSE_1_0.txt *
|
||||
*******************************************************************************/
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cmath>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
#include <numeric>
|
||||
#include <algorithm>
|
||||
|
||||
#include "clipper2/clipper.engine.h"
|
||||
#include "clipper2/clipper.h"
|
||||
#include <stdexcept>
|
||||
|
||||
// https://github.com/AngusJohnson/Clipper2/discussions/334
|
||||
// #discussioncomment-4248602
|
||||
@@ -85,7 +79,7 @@ namespace Clipper2Lib {
|
||||
inline bool IsOpenEnd(const Vertex& v)
|
||||
{
|
||||
return (v.flags & (VertexFlags::OpenStart | VertexFlags::OpenEnd)) !=
|
||||
VertexFlags::None;
|
||||
VertexFlags::Empty;
|
||||
}
|
||||
|
||||
|
||||
@@ -220,7 +214,7 @@ namespace Clipper2Lib {
|
||||
|
||||
inline bool IsMaxima(const Vertex& v)
|
||||
{
|
||||
return ((v.flags & VertexFlags::LocalMax) != VertexFlags::None);
|
||||
return ((v.flags & VertexFlags::LocalMax) != VertexFlags::Empty);
|
||||
}
|
||||
|
||||
|
||||
@@ -235,12 +229,12 @@ namespace Clipper2Lib {
|
||||
if (e.wind_dx > 0)
|
||||
while ((result->next->pt.y == result->pt.y) &&
|
||||
((result->flags & (VertexFlags::OpenEnd |
|
||||
VertexFlags::LocalMax)) == VertexFlags::None))
|
||||
VertexFlags::LocalMax)) == VertexFlags::Empty))
|
||||
result = result->next;
|
||||
else
|
||||
while (result->prev->pt.y == result->pt.y &&
|
||||
((result->flags & (VertexFlags::OpenEnd |
|
||||
VertexFlags::LocalMax)) == VertexFlags::None))
|
||||
VertexFlags::LocalMax)) == VertexFlags::Empty))
|
||||
result = result->prev;
|
||||
if (!IsMaxima(*result)) result = nullptr; // not a maxima
|
||||
return result;
|
||||
@@ -478,7 +472,7 @@ namespace Clipper2Lib {
|
||||
|
||||
inline bool IsJoined(const Active& e)
|
||||
{
|
||||
return e.join_with != JoinWith::None;
|
||||
return e.join_with != JoinWith::NoJoin;
|
||||
}
|
||||
|
||||
inline void SetOwner(OutRec* outrec, OutRec* new_owner)
|
||||
@@ -517,7 +511,7 @@ namespace Clipper2Lib {
|
||||
while (op2 != op && op2->pt.y > pt.y) op2 = op2->next;
|
||||
if (op2 == op) break;
|
||||
|
||||
// must have touched or crossed the pt.Y horizonal
|
||||
// must have touched or crossed the pt.Y horizontal
|
||||
// and this must happen an even number of times
|
||||
|
||||
if (op2->pt.y == pt.y) // touching the horizontal
|
||||
@@ -564,7 +558,7 @@ namespace Clipper2Lib {
|
||||
while (op2->next != op &&
|
||||
((op2->pt.x == op2->next->pt.x && op2->pt.x == op2->prev->pt.x) ||
|
||||
(op2->pt.y == op2->next->pt.y && op2->pt.y == op2->prev->pt.y))) op2 = op2->next;
|
||||
result.push_back(op2->pt);
|
||||
result.emplace_back(op2->pt);
|
||||
OutPt* prevOp = op2;
|
||||
op2 = op2->next;
|
||||
while (op2 != op)
|
||||
@@ -572,7 +566,7 @@ namespace Clipper2Lib {
|
||||
if ((op2->pt.x != op2->next->pt.x || op2->pt.x != prevOp->pt.x) &&
|
||||
(op2->pt.y != op2->next->pt.y || op2->pt.y != prevOp->pt.y))
|
||||
{
|
||||
result.push_back(op2->pt);
|
||||
result.emplace_back(op2->pt);
|
||||
prevOp = op2;
|
||||
}
|
||||
op2 = op2->next;
|
||||
@@ -608,10 +602,10 @@ namespace Clipper2Lib {
|
||||
Vertex& vert, PathType polytype, bool is_open)
|
||||
{
|
||||
//make sure the vertex is added only once ...
|
||||
if ((VertexFlags::LocalMin & vert.flags) != VertexFlags::None) return;
|
||||
if ((VertexFlags::LocalMin & vert.flags) != VertexFlags::Empty) return;
|
||||
|
||||
vert.flags = (vert.flags | VertexFlags::LocalMin);
|
||||
list.push_back(std::make_unique <LocalMinima>(&vert, polytype, is_open));
|
||||
list.emplace_back(std::make_unique <LocalMinima>(&vert, polytype, is_open));
|
||||
}
|
||||
|
||||
void AddPaths_(const Paths64& paths, PathType polytype, bool is_open,
|
||||
@@ -643,7 +637,7 @@ namespace Clipper2Lib {
|
||||
}
|
||||
curr_v->prev = prev_v;
|
||||
curr_v->pt = pt;
|
||||
curr_v->flags = VertexFlags::None;
|
||||
curr_v->flags = VertexFlags::Empty;
|
||||
prev_v = curr_v++;
|
||||
cnt++;
|
||||
}
|
||||
@@ -725,10 +719,10 @@ namespace Clipper2Lib {
|
||||
void ReuseableDataContainer64::AddLocMin(Vertex& vert, PathType polytype, bool is_open)
|
||||
{
|
||||
//make sure the vertex is added only once ...
|
||||
if ((VertexFlags::LocalMin & vert.flags) != VertexFlags::None) return;
|
||||
if ((VertexFlags::LocalMin & vert.flags) != VertexFlags::Empty) return;
|
||||
|
||||
vert.flags = (vert.flags | VertexFlags::LocalMin);
|
||||
minima_list_.push_back(std::make_unique <LocalMinima>(&vert, polytype, is_open));
|
||||
minima_list_.emplace_back(std::make_unique <LocalMinima>(&vert, polytype, is_open));
|
||||
}
|
||||
|
||||
void ReuseableDataContainer64::AddPaths(const Paths64& paths,
|
||||
@@ -836,9 +830,7 @@ namespace Clipper2Lib {
|
||||
|
||||
void ClipperBase::AddPath(const Path64& path, PathType polytype, bool is_open)
|
||||
{
|
||||
Paths64 tmp;
|
||||
tmp.push_back(path);
|
||||
AddPaths(tmp, polytype, is_open);
|
||||
AddPaths(Paths64(1, path), polytype, is_open);
|
||||
}
|
||||
|
||||
void ClipperBase::AddPaths(const Paths64& paths, PathType polytype, bool is_open)
|
||||
@@ -857,7 +849,7 @@ namespace Clipper2Lib {
|
||||
LocalMinimaList::const_iterator i;
|
||||
for (i = reuseable_data.minima_list_.cbegin(); i != reuseable_data.minima_list_.cend(); ++i)
|
||||
{
|
||||
minima_list_.push_back(std::make_unique <LocalMinima>((*i)->vertex, (*i)->polytype, (*i)->is_open));
|
||||
minima_list_.emplace_back(std::make_unique <LocalMinima>((*i)->vertex, (*i)->polytype, (*i)->is_open));
|
||||
if ((*i)->is_open) has_open_paths_ = true;
|
||||
}
|
||||
}
|
||||
@@ -907,10 +899,10 @@ namespace Clipper2Lib {
|
||||
void ClipperBase::AddLocMin(Vertex& vert, PathType polytype, bool is_open)
|
||||
{
|
||||
//make sure the vertex is added only once ...
|
||||
if ((VertexFlags::LocalMin & vert.flags) != VertexFlags::None) return;
|
||||
if ((VertexFlags::LocalMin & vert.flags) != VertexFlags::Empty) return;
|
||||
|
||||
vert.flags = (vert.flags | VertexFlags::LocalMin);
|
||||
minima_list_.push_back(std::make_unique <LocalMinima>(&vert, polytype, is_open));
|
||||
minima_list_.emplace_back(std::make_unique <LocalMinima>(&vert, polytype, is_open));
|
||||
}
|
||||
|
||||
bool ClipperBase::IsContributingClosed(const Active& e) const
|
||||
@@ -928,11 +920,14 @@ namespace Clipper2Lib {
|
||||
case FillRule::Negative:
|
||||
if (e.wind_cnt != -1) return false;
|
||||
break;
|
||||
// Should never happen, but adding this to stop a compiler warning
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (cliptype_)
|
||||
{
|
||||
case ClipType::None:
|
||||
case ClipType::NoClip:
|
||||
return false;
|
||||
case ClipType::Intersection:
|
||||
switch (fillrule_)
|
||||
@@ -978,6 +973,9 @@ namespace Clipper2Lib {
|
||||
break;
|
||||
|
||||
case ClipType::Xor: return true; break;
|
||||
// Should never happen, but adding this to stop a compiler warning
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false; // we should never get here
|
||||
}
|
||||
@@ -1208,7 +1206,7 @@ namespace Clipper2Lib {
|
||||
|
||||
while (PopLocalMinima(bot_y, local_minima))
|
||||
{
|
||||
if ((local_minima->vertex->flags & VertexFlags::OpenStart) != VertexFlags::None)
|
||||
if ((local_minima->vertex->flags & VertexFlags::OpenStart) != VertexFlags::Empty)
|
||||
{
|
||||
left_bound = nullptr;
|
||||
}
|
||||
@@ -1224,7 +1222,7 @@ namespace Clipper2Lib {
|
||||
SetDx(*left_bound);
|
||||
}
|
||||
|
||||
if ((local_minima->vertex->flags & VertexFlags::OpenEnd) != VertexFlags::None)
|
||||
if ((local_minima->vertex->flags & VertexFlags::OpenEnd) != VertexFlags::Empty)
|
||||
{
|
||||
right_bound = nullptr;
|
||||
}
|
||||
@@ -1488,7 +1486,7 @@ namespace Clipper2Lib {
|
||||
{
|
||||
OutRec* result = new OutRec();
|
||||
result->idx = outrec_list_.size();
|
||||
outrec_list_.push_back(result);
|
||||
outrec_list_.emplace_back(result);
|
||||
result->pts = nullptr;
|
||||
result->owner = nullptr;
|
||||
result->polypath = nullptr;
|
||||
@@ -1631,12 +1629,12 @@ namespace Clipper2Lib {
|
||||
if (Path1InsidePath2(prevOp, newOp))
|
||||
{
|
||||
newOr->splits = new OutRecList();
|
||||
newOr->splits->push_back(outrec);
|
||||
newOr->splits->emplace_back(outrec);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!outrec->splits) outrec->splits = new OutRecList();
|
||||
outrec->splits->push_back(newOr);
|
||||
outrec->splits->emplace_back(newOr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1955,7 +1953,7 @@ namespace Clipper2Lib {
|
||||
else if (IsFront(e1) || (e1.outrec == e2.outrec))
|
||||
{
|
||||
//this 'else if' condition isn't strictly needed but
|
||||
//it's sensible to split polygons that ony touch at
|
||||
//it's sensible to split polygons that only touch at
|
||||
//a common vertex (not at common edges).
|
||||
|
||||
#ifdef USINGZ
|
||||
@@ -2125,7 +2123,7 @@ namespace Clipper2Lib {
|
||||
using_polytree_ = use_polytrees;
|
||||
Reset();
|
||||
int64_t y;
|
||||
if (ct == ClipType::None || !PopScanline(y)) return true;
|
||||
if (ct == ClipType::NoClip || !PopScanline(y)) return true;
|
||||
|
||||
while (succeeded_)
|
||||
{
|
||||
@@ -2239,7 +2237,7 @@ namespace Clipper2Lib {
|
||||
HorzJoin join = HorzJoin(
|
||||
DuplicateOp(hs1->left_op, true),
|
||||
DuplicateOp(hs2->left_op, false));
|
||||
horz_join_list_.push_back(join);
|
||||
horz_join_list_.emplace_back(join);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2252,7 +2250,7 @@ namespace Clipper2Lib {
|
||||
HorzJoin join = HorzJoin(
|
||||
DuplicateOp(hs2->left_op, true),
|
||||
DuplicateOp(hs1->left_op, false));
|
||||
horz_join_list_.push_back(join);
|
||||
horz_join_list_.emplace_back(join);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2264,7 +2262,7 @@ namespace Clipper2Lib {
|
||||
if (!toOr->splits) toOr->splits = new OutRecList();
|
||||
OutRecList::iterator orIter = fromOr->splits->begin();
|
||||
for (; orIter != fromOr->splits->end(); ++orIter)
|
||||
toOr->splits->push_back(*orIter);
|
||||
toOr->splits->emplace_back(*orIter);
|
||||
fromOr->splits->clear();
|
||||
}
|
||||
|
||||
@@ -2317,7 +2315,7 @@ namespace Clipper2Lib {
|
||||
or2->owner = or1->owner;
|
||||
|
||||
if (!or1->splits) or1->splits = new OutRecList();
|
||||
or1->splits->push_back(or2);
|
||||
or1->splits->emplace_back(or2);
|
||||
}
|
||||
else
|
||||
or2->owner = or1;
|
||||
@@ -2376,7 +2374,7 @@ namespace Clipper2Lib {
|
||||
else ip.x = TopX(e2, ip.y);
|
||||
}
|
||||
}
|
||||
intersect_nodes_.push_back(IntersectNode(&e1, &e2, ip));
|
||||
intersect_nodes_.emplace_back(&e1, &e2, ip);
|
||||
}
|
||||
|
||||
bool ClipperBase::BuildIntersectList(const int64_t top_y)
|
||||
@@ -2497,7 +2495,7 @@ namespace Clipper2Lib {
|
||||
void ClipperBase::AddTrialHorzJoin(OutPt* op)
|
||||
{
|
||||
if (op->outrec->is_open) return;
|
||||
horz_seg_list_.push_back(HorzSegment(op));
|
||||
horz_seg_list_.emplace_back(op);
|
||||
}
|
||||
|
||||
bool ClipperBase::ResetHorzDirection(const Active& horz,
|
||||
@@ -2655,7 +2653,7 @@ namespace Clipper2Lib {
|
||||
|
||||
if (horz.outrec)
|
||||
{
|
||||
//nb: The outrec containining the op returned by IntersectEdges
|
||||
//nb: The outrec containing the op returned by IntersectEdges
|
||||
//above may no longer be associated with horzEdge.
|
||||
AddTrialHorzJoin(GetLastOp(horz));
|
||||
}
|
||||
@@ -2789,14 +2787,14 @@ namespace Clipper2Lib {
|
||||
{
|
||||
if (e.join_with == JoinWith::Right)
|
||||
{
|
||||
e.join_with = JoinWith::None;
|
||||
e.next_in_ael->join_with = JoinWith::None;
|
||||
e.join_with = JoinWith::NoJoin;
|
||||
e.next_in_ael->join_with = JoinWith::NoJoin;
|
||||
AddLocalMinPoly(e, *e.next_in_ael, pt, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
e.join_with = JoinWith::None;
|
||||
e.prev_in_ael->join_with = JoinWith::None;
|
||||
e.join_with = JoinWith::NoJoin;
|
||||
e.prev_in_ael->join_with = JoinWith::NoJoin;
|
||||
AddLocalMinPoly(*e.prev_in_ael, e, pt, true);
|
||||
}
|
||||
}
|
||||
@@ -2899,14 +2897,14 @@ namespace Clipper2Lib {
|
||||
lastPt = op->pt;
|
||||
op2 = op->next;
|
||||
}
|
||||
path.push_back(lastPt);
|
||||
path.emplace_back(lastPt);
|
||||
|
||||
while (op2 != op)
|
||||
{
|
||||
if (op2->pt != lastPt)
|
||||
{
|
||||
lastPt = op2->pt;
|
||||
path.push_back(lastPt);
|
||||
path.emplace_back(lastPt);
|
||||
}
|
||||
if (reverse)
|
||||
op2 = op2->prev;
|
||||
@@ -3031,7 +3029,7 @@ namespace Clipper2Lib {
|
||||
{
|
||||
Path64 path;
|
||||
if (BuildPath64(outrec->pts, reverse_solution_, true, path))
|
||||
open_paths.push_back(path);
|
||||
open_paths.emplace_back(std::move(path));
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -3060,9 +3058,9 @@ namespace Clipper2Lib {
|
||||
op2 = op->next;
|
||||
}
|
||||
#ifdef USINGZ
|
||||
path.push_back(PointD(lastPt.x * inv_scale, lastPt.y * inv_scale, lastPt.z));
|
||||
path.emplace_back(lastPt.x * inv_scale, lastPt.y * inv_scale, lastPt.z);
|
||||
#else
|
||||
path.push_back(PointD(lastPt.x * inv_scale, lastPt.y * inv_scale));
|
||||
path.emplace_back(lastPt.x * inv_scale, lastPt.y * inv_scale);
|
||||
#endif
|
||||
|
||||
while (op2 != op)
|
||||
@@ -3071,9 +3069,9 @@ namespace Clipper2Lib {
|
||||
{
|
||||
lastPt = op2->pt;
|
||||
#ifdef USINGZ
|
||||
path.push_back(PointD(lastPt.x * inv_scale, lastPt.y * inv_scale, lastPt.z));
|
||||
path.emplace_back(lastPt.x * inv_scale, lastPt.y * inv_scale, lastPt.z);
|
||||
#else
|
||||
path.push_back(PointD(lastPt.x * inv_scale, lastPt.y * inv_scale));
|
||||
path.emplace_back(lastPt.x * inv_scale, lastPt.y * inv_scale);
|
||||
#endif
|
||||
|
||||
}
|
||||
@@ -3137,7 +3135,7 @@ namespace Clipper2Lib {
|
||||
{
|
||||
PathD path;
|
||||
if (BuildPathD(outrec->pts, reverse_solution_, true, path, invScale_))
|
||||
open_paths.push_back(path);
|
||||
open_paths.emplace_back(std::move(path));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user