Fix Clipper2 build with GCC13
This commit is contained in:
parent
fbe776aaaa
commit
2bca1fc9f3
|
@ -17,6 +17,8 @@ constexpr auto CLIPPER2_VERSION = "1.0.6";
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
#include "clipper.core.h"
|
#include "clipper.core.h"
|
||||||
|
|
||||||
namespace Clipper2Lib {
|
namespace Clipper2Lib {
|
||||||
|
@ -31,19 +33,19 @@ namespace Clipper2Lib {
|
||||||
|
|
||||||
//Note: all clipping operations except for Difference are commutative.
|
//Note: all clipping operations except for Difference are commutative.
|
||||||
enum class ClipType { None, Intersection, Union, Difference, Xor };
|
enum class ClipType { None, Intersection, Union, Difference, Xor };
|
||||||
|
|
||||||
enum class PathType { Subject, Clip };
|
enum class PathType { Subject, Clip };
|
||||||
|
|
||||||
enum class VertexFlags : uint32_t {
|
enum class VertexFlags : uint32_t {
|
||||||
None = 0, OpenStart = 1, OpenEnd = 2, LocalMax = 4, LocalMin = 8
|
None = 0, OpenStart = 1, OpenEnd = 2, LocalMax = 4, LocalMin = 8
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr enum VertexFlags operator &(enum VertexFlags a, enum VertexFlags b)
|
constexpr enum VertexFlags operator &(enum VertexFlags a, enum VertexFlags b)
|
||||||
{
|
{
|
||||||
return (enum VertexFlags)(uint32_t(a) & uint32_t(b));
|
return (enum VertexFlags)(uint32_t(a) & uint32_t(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr enum VertexFlags operator |(enum VertexFlags a, enum VertexFlags b)
|
constexpr enum VertexFlags operator |(enum VertexFlags a, enum VertexFlags b)
|
||||||
{
|
{
|
||||||
return (enum VertexFlags)(uint32_t(a) | uint32_t(b));
|
return (enum VertexFlags)(uint32_t(a) | uint32_t(b));
|
||||||
}
|
}
|
||||||
|
@ -97,7 +99,7 @@ namespace Clipper2Lib {
|
||||||
//Important: UP and DOWN here are premised on Y-axis positive down
|
//Important: UP and DOWN here are premised on Y-axis positive down
|
||||||
//displays, which is the orientation used in Clipper's development.
|
//displays, which is the orientation used in Clipper's development.
|
||||||
///////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
struct Active {
|
struct Active {
|
||||||
Point64 bot;
|
Point64 bot;
|
||||||
Point64 top;
|
Point64 top;
|
||||||
|
@ -168,7 +170,7 @@ namespace Clipper2Lib {
|
||||||
std::vector<LocalMinima*>::iterator current_locmin_iter_;
|
std::vector<LocalMinima*>::iterator current_locmin_iter_;
|
||||||
std::vector<Vertex*> vertex_lists_;
|
std::vector<Vertex*> vertex_lists_;
|
||||||
std::priority_queue<int64_t> scanline_list_;
|
std::priority_queue<int64_t> scanline_list_;
|
||||||
std::vector<IntersectNode> intersect_nodes_;
|
std::vector<IntersectNode> intersect_nodes_;
|
||||||
std::vector<Joiner*> joiner_list_; //pointers in case of memory reallocs
|
std::vector<Joiner*> joiner_list_; //pointers in case of memory reallocs
|
||||||
void Reset();
|
void Reset();
|
||||||
void InsertScanline(int64_t y);
|
void InsertScanline(int64_t y);
|
||||||
|
@ -197,7 +199,7 @@ namespace Clipper2Lib {
|
||||||
void ProcessIntersectList();
|
void ProcessIntersectList();
|
||||||
void SwapPositionsInAEL(Active& edge1, Active& edge2);
|
void SwapPositionsInAEL(Active& edge1, Active& edge2);
|
||||||
OutPt* AddOutPt(const Active &e, const Point64& pt);
|
OutPt* AddOutPt(const Active &e, const Point64& pt);
|
||||||
OutPt* AddLocalMinPoly(Active &e1, Active &e2,
|
OutPt* AddLocalMinPoly(Active &e1, Active &e2,
|
||||||
const Point64& pt, bool is_new = false);
|
const Point64& pt, bool is_new = false);
|
||||||
OutPt* AddLocalMaxPoly(Active &e1, Active &e2, const Point64& pt);
|
OutPt* AddLocalMaxPoly(Active &e1, Active &e2, const Point64& pt);
|
||||||
void DoHorizontal(Active &horz);
|
void DoHorizontal(Active &horz);
|
||||||
|
@ -254,7 +256,7 @@ namespace Clipper2Lib {
|
||||||
PolyPath* parent_;
|
PolyPath* parent_;
|
||||||
public:
|
public:
|
||||||
PolyPath(PolyPath* parent = nullptr): parent_(parent){}
|
PolyPath(PolyPath* parent = nullptr): parent_(parent){}
|
||||||
virtual ~PolyPath() { Clear(); };
|
virtual ~PolyPath() { Clear(); };
|
||||||
//https://en.cppreference.com/w/cpp/language/rule_of_three
|
//https://en.cppreference.com/w/cpp/language/rule_of_three
|
||||||
PolyPath(const PolyPath&) = delete;
|
PolyPath(const PolyPath&) = delete;
|
||||||
PolyPath& operator=(const PolyPath&) = delete;
|
PolyPath& operator=(const PolyPath&) = delete;
|
||||||
|
@ -274,7 +276,7 @@ namespace Clipper2Lib {
|
||||||
|
|
||||||
const PolyPath* Parent() const { return parent_; }
|
const PolyPath* Parent() const { return parent_; }
|
||||||
|
|
||||||
bool IsHole() const
|
bool IsHole() const
|
||||||
{
|
{
|
||||||
const PolyPath* pp = parent_;
|
const PolyPath* pp = parent_;
|
||||||
bool is_hole = pp;
|
bool is_hole = pp;
|
||||||
|
@ -364,13 +366,13 @@ namespace Clipper2Lib {
|
||||||
PathD polygon_;
|
PathD polygon_;
|
||||||
typedef typename std::vector<PolyPathD*>::const_iterator ppD_itor;
|
typedef typename std::vector<PolyPathD*>::const_iterator ppD_itor;
|
||||||
public:
|
public:
|
||||||
PolyPathD(PolyPathD* parent = nullptr) : PolyPath(parent)
|
PolyPathD(PolyPathD* parent = nullptr) : PolyPath(parent)
|
||||||
{
|
{
|
||||||
inv_scale_ = parent ? parent->inv_scale_ : 1.0;
|
inv_scale_ = parent ? parent->inv_scale_ : 1.0;
|
||||||
}
|
}
|
||||||
PolyPathD* operator [] (size_t index)
|
PolyPathD* operator [] (size_t index)
|
||||||
{
|
{
|
||||||
return static_cast<PolyPathD*>(childs_[index]);
|
return static_cast<PolyPathD*>(childs_[index]);
|
||||||
}
|
}
|
||||||
ppD_itor begin() const { return childs_.cbegin(); }
|
ppD_itor begin() const { return childs_.cbegin(); }
|
||||||
ppD_itor end() const { return childs_.cend(); }
|
ppD_itor end() const { return childs_.cend(); }
|
||||||
|
@ -437,7 +439,7 @@ namespace Clipper2Lib {
|
||||||
return Execute(clip_type, fill_rule, closed_paths, dummy);
|
return Execute(clip_type, fill_rule, closed_paths, dummy);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Execute(ClipType clip_type, FillRule fill_rule,
|
bool Execute(ClipType clip_type, FillRule fill_rule,
|
||||||
Paths64& closed_paths, Paths64& open_paths)
|
Paths64& closed_paths, Paths64& open_paths)
|
||||||
{
|
{
|
||||||
closed_paths.clear();
|
closed_paths.clear();
|
||||||
|
@ -509,12 +511,12 @@ namespace Clipper2Lib {
|
||||||
void CheckCallback()
|
void CheckCallback()
|
||||||
{
|
{
|
||||||
if(zCallback_)
|
if(zCallback_)
|
||||||
// if the user defined float point callback has been assigned
|
// if the user defined float point callback has been assigned
|
||||||
// then assign the proxy callback function
|
// then assign the proxy callback function
|
||||||
ClipperBase::zCallback_ =
|
ClipperBase::zCallback_ =
|
||||||
std::bind(&ClipperD::ZCB, this, std::placeholders::_1,
|
std::bind(&ClipperD::ZCB, this, std::placeholders::_1,
|
||||||
std::placeholders::_2, std::placeholders::_3,
|
std::placeholders::_2, std::placeholders::_3,
|
||||||
std::placeholders::_4, std::placeholders::_5);
|
std::placeholders::_4, std::placeholders::_5);
|
||||||
else
|
else
|
||||||
ClipperBase::zCallback_ = nullptr;
|
ClipperBase::zCallback_ = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -581,6 +583,6 @@ namespace Clipper2Lib {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
#endif // CLIPPER_ENGINE_H
|
#endif // CLIPPER_ENGINE_H
|
||||||
|
|
|
@ -15,6 +15,9 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include "clipper2/clipper.engine.h"
|
#include "clipper2/clipper.engine.h"
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
namespace Clipper2Lib {
|
namespace Clipper2Lib {
|
||||||
|
|
||||||
static const double FloatingPointTolerance = 1.0e-12;
|
static const double FloatingPointTolerance = 1.0e-12;
|
||||||
|
@ -94,7 +97,7 @@ namespace Clipper2Lib {
|
||||||
|
|
||||||
inline bool IsOpenEnd(const Vertex& v)
|
inline bool IsOpenEnd(const Vertex& v)
|
||||||
{
|
{
|
||||||
return (v.flags & (VertexFlags::OpenStart | VertexFlags::OpenEnd)) !=
|
return (v.flags & (VertexFlags::OpenStart | VertexFlags::OpenEnd)) !=
|
||||||
VertexFlags::None;
|
VertexFlags::None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,8 +192,8 @@ namespace Clipper2Lib {
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Point64 GetEndE1ClosestToEndE2(
|
inline Point64 GetEndE1ClosestToEndE2(
|
||||||
const Active& e1, const Active& e2)
|
const Active& e1, const Active& e2)
|
||||||
{
|
{
|
||||||
double d[] = {
|
double d[] = {
|
||||||
DistanceSqr(e1.bot, e2.bot),
|
DistanceSqr(e1.bot, e2.bot),
|
||||||
DistanceSqr(e1.top, e2.top),
|
DistanceSqr(e1.top, e2.top),
|
||||||
|
@ -204,7 +207,7 @@ namespace Clipper2Lib {
|
||||||
if (d[i] < d[idx]) idx = i;
|
if (d[i] < d[idx]) idx = i;
|
||||||
if (d[i] == 0) break;
|
if (d[i] == 0) break;
|
||||||
}
|
}
|
||||||
switch (idx)
|
switch (idx)
|
||||||
{
|
{
|
||||||
case 1: case 2: return e1.top;
|
case 1: case 2: return e1.top;
|
||||||
default: return e1.bot;
|
default: return e1.bot;
|
||||||
|
@ -214,7 +217,7 @@ namespace Clipper2Lib {
|
||||||
Point64 GetIntersectPoint(const Active& e1, const Active& e2)
|
Point64 GetIntersectPoint(const Active& e1, const Active& e2)
|
||||||
{
|
{
|
||||||
double b1, b2, q = (e1.dx - e2.dx);
|
double b1, b2, q = (e1.dx - e2.dx);
|
||||||
if (std::abs(q) < 1e-5) // 1e-5 is a rough empirical limit
|
if (std::abs(q) < 1e-5) // 1e-5 is a rough empirical limit
|
||||||
return GetEndE1ClosestToEndE2(e1, e2); // ie almost parallel
|
return GetEndE1ClosestToEndE2(e1, e2); // ie almost parallel
|
||||||
|
|
||||||
if (e1.dx == 0)
|
if (e1.dx == 0)
|
||||||
|
@ -235,7 +238,7 @@ namespace Clipper2Lib {
|
||||||
{
|
{
|
||||||
b1 = e1.bot.x - e1.bot.y * e1.dx;
|
b1 = e1.bot.x - e1.bot.y * e1.dx;
|
||||||
b2 = e2.bot.x - e2.bot.y * e2.dx;
|
b2 = e2.bot.x - e2.bot.y * e2.dx;
|
||||||
|
|
||||||
q = (b2 - b1) / q;
|
q = (b2 - b1) / q;
|
||||||
return (abs(e1.dx) < abs(e2.dx)) ?
|
return (abs(e1.dx) < abs(e2.dx)) ?
|
||||||
Point64(static_cast<int64_t>(e1.dx * q + b1),
|
Point64(static_cast<int64_t>(e1.dx * q + b1),
|
||||||
|
@ -306,7 +309,7 @@ namespace Clipper2Lib {
|
||||||
|
|
||||||
|
|
||||||
//PrevPrevVertex: useful to get the (inverted Y-axis) top of the
|
//PrevPrevVertex: useful to get the (inverted Y-axis) top of the
|
||||||
//alternate edge (ie left or right bound) during edge insertion.
|
//alternate edge (ie left or right bound) during edge insertion.
|
||||||
inline Vertex* PrevPrevVertex(const Active& ae)
|
inline Vertex* PrevPrevVertex(const Active& ae)
|
||||||
{
|
{
|
||||||
if (ae.wind_dx > 0)
|
if (ae.wind_dx > 0)
|
||||||
|
@ -353,7 +356,7 @@ namespace Clipper2Lib {
|
||||||
while (result->next->pt.y == result->pt.y) result = result->next;
|
while (result->next->pt.y == result->pt.y) result = result->next;
|
||||||
else
|
else
|
||||||
while (result->prev->pt.y == result->pt.y) result = result->prev;
|
while (result->prev->pt.y == result->pt.y) result = result->prev;
|
||||||
if (!IsMaxima(*result)) result = nullptr; // not a maxima
|
if (!IsMaxima(*result)) result = nullptr; // not a maxima
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -494,7 +497,7 @@ namespace Clipper2Lib {
|
||||||
return result * 0.5;
|
return result * 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline double AreaTriangle(const Point64& pt1,
|
inline double AreaTriangle(const Point64& pt1,
|
||||||
const Point64& pt2, const Point64& pt3)
|
const Point64& pt2, const Point64& pt3)
|
||||||
{
|
{
|
||||||
return (static_cast<double>(pt3.y + pt1.y) * static_cast<double>(pt3.x - pt1.x) +
|
return (static_cast<double>(pt3.y + pt1.y) * static_cast<double>(pt3.x - pt1.x) +
|
||||||
|
@ -630,7 +633,7 @@ namespace Clipper2Lib {
|
||||||
Clear();
|
Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClipperBase::DeleteEdges(Active*& e)
|
void ClipperBase::DeleteEdges(Active*& e)
|
||||||
{
|
{
|
||||||
while (e)
|
while (e)
|
||||||
{
|
{
|
||||||
|
@ -681,7 +684,7 @@ namespace Clipper2Lib {
|
||||||
void ClipperBase::SetZ(const Active& e1, const Active& e2, Point64& ip)
|
void ClipperBase::SetZ(const Active& e1, const Active& e2, Point64& ip)
|
||||||
{
|
{
|
||||||
if (!zCallback_) return;
|
if (!zCallback_) return;
|
||||||
// prioritize subject over clip vertices by passing
|
// prioritize subject over clip vertices by passing
|
||||||
// subject vertices before clip vertices in the callback
|
// subject vertices before clip vertices in the callback
|
||||||
if (GetPolyType(e1) == PathType::Subject)
|
if (GetPolyType(e1) == PathType::Subject)
|
||||||
{
|
{
|
||||||
|
@ -872,19 +875,19 @@ namespace Clipper2Lib {
|
||||||
case FillRule::EvenOdd:
|
case FillRule::EvenOdd:
|
||||||
break;
|
break;
|
||||||
case FillRule::NonZero:
|
case FillRule::NonZero:
|
||||||
if (abs(e.wind_cnt) != 1) return false;
|
if (abs(e.wind_cnt) != 1) return false;
|
||||||
break;
|
break;
|
||||||
case FillRule::Positive:
|
case FillRule::Positive:
|
||||||
if (e.wind_cnt != 1) return false;
|
if (e.wind_cnt != 1) return false;
|
||||||
break;
|
break;
|
||||||
case FillRule::Negative:
|
case FillRule::Negative:
|
||||||
if (e.wind_cnt != -1) return false;
|
if (e.wind_cnt != -1) return false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (cliptype_)
|
switch (cliptype_)
|
||||||
{
|
{
|
||||||
case ClipType::None:
|
case ClipType::None:
|
||||||
return false;
|
return false;
|
||||||
case ClipType::Intersection:
|
case ClipType::Intersection:
|
||||||
switch (fillrule_)
|
switch (fillrule_)
|
||||||
|
@ -914,17 +917,17 @@ namespace Clipper2Lib {
|
||||||
bool result;
|
bool result;
|
||||||
switch (fillrule_)
|
switch (fillrule_)
|
||||||
{
|
{
|
||||||
case FillRule::Positive:
|
case FillRule::Positive:
|
||||||
result = (e.wind_cnt2 <= 0);
|
result = (e.wind_cnt2 <= 0);
|
||||||
break;
|
break;
|
||||||
case FillRule::Negative:
|
case FillRule::Negative:
|
||||||
result = (e.wind_cnt2 >= 0);
|
result = (e.wind_cnt2 >= 0);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
result = (e.wind_cnt2 == 0);
|
result = (e.wind_cnt2 == 0);
|
||||||
}
|
}
|
||||||
if (GetPolyType(e) == PathType::Subject)
|
if (GetPolyType(e) == PathType::Subject)
|
||||||
return result;
|
return result;
|
||||||
else
|
else
|
||||||
return !result;
|
return !result;
|
||||||
break;
|
break;
|
||||||
|
@ -940,15 +943,15 @@ namespace Clipper2Lib {
|
||||||
bool is_in_clip, is_in_subj;
|
bool is_in_clip, is_in_subj;
|
||||||
switch (fillrule_)
|
switch (fillrule_)
|
||||||
{
|
{
|
||||||
case FillRule::Positive:
|
case FillRule::Positive:
|
||||||
is_in_clip = e.wind_cnt2 > 0;
|
is_in_clip = e.wind_cnt2 > 0;
|
||||||
is_in_subj = e.wind_cnt > 0;
|
is_in_subj = e.wind_cnt > 0;
|
||||||
break;
|
break;
|
||||||
case FillRule::Negative:
|
case FillRule::Negative:
|
||||||
is_in_clip = e.wind_cnt2 < 0;
|
is_in_clip = e.wind_cnt2 < 0;
|
||||||
is_in_subj = e.wind_cnt < 0;
|
is_in_subj = e.wind_cnt < 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
is_in_clip = e.wind_cnt2 != 0;
|
is_in_clip = e.wind_cnt2 != 0;
|
||||||
is_in_subj = e.wind_cnt != 0;
|
is_in_subj = e.wind_cnt != 0;
|
||||||
}
|
}
|
||||||
|
@ -1085,15 +1088,15 @@ namespace Clipper2Lib {
|
||||||
//the direction they're about to turn
|
//the direction they're about to turn
|
||||||
if (!IsMaxima(resident) && (resident.top.y > newcomer.top.y))
|
if (!IsMaxima(resident) && (resident.top.y > newcomer.top.y))
|
||||||
{
|
{
|
||||||
return CrossProduct(newcomer.bot,
|
return CrossProduct(newcomer.bot,
|
||||||
resident.top, NextVertex(resident)->pt) <= 0;
|
resident.top, NextVertex(resident)->pt) <= 0;
|
||||||
}
|
}
|
||||||
else if (!IsMaxima(newcomer) && (newcomer.top.y > resident.top.y))
|
else if (!IsMaxima(newcomer) && (newcomer.top.y > resident.top.y))
|
||||||
{
|
{
|
||||||
return CrossProduct(newcomer.bot,
|
return CrossProduct(newcomer.bot,
|
||||||
newcomer.top, NextVertex(newcomer)->pt) >= 0;
|
newcomer.top, NextVertex(newcomer)->pt) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t y = newcomer.bot.y;
|
int64_t y = newcomer.bot.y;
|
||||||
bool newcomerIsLeft = newcomer.is_left_bound;
|
bool newcomerIsLeft = newcomer.is_left_bound;
|
||||||
|
|
||||||
|
@ -1103,7 +1106,7 @@ namespace Clipper2Lib {
|
||||||
else if (resident.is_left_bound != newcomerIsLeft)
|
else if (resident.is_left_bound != newcomerIsLeft)
|
||||||
return newcomerIsLeft;
|
return newcomerIsLeft;
|
||||||
else if (CrossProduct(PrevPrevVertex(resident)->pt,
|
else if (CrossProduct(PrevPrevVertex(resident)->pt,
|
||||||
resident.bot, resident.top) == 0) return true;
|
resident.bot, resident.top) == 0) return true;
|
||||||
else
|
else
|
||||||
//compare turning direction of the alternate bound
|
//compare turning direction of the alternate bound
|
||||||
return (CrossProduct(PrevPrevVertex(resident)->pt,
|
return (CrossProduct(PrevPrevVertex(resident)->pt,
|
||||||
|
@ -1319,7 +1322,7 @@ namespace Clipper2Lib {
|
||||||
SetSides(*outrec, e1, e2);
|
SetSides(*outrec, e1, e2);
|
||||||
else
|
else
|
||||||
SetSides(*outrec, e2, e1);
|
SetSides(*outrec, e2, e1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Active* prevHotEdge = GetPrevHotEdge(e1);
|
Active* prevHotEdge = GetPrevHotEdge(e1);
|
||||||
|
@ -1335,7 +1338,7 @@ namespace Clipper2Lib {
|
||||||
else
|
else
|
||||||
SetSides(*outrec, e1, e2);
|
SetSides(*outrec, e1, e2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
outrec->owner = nullptr;
|
outrec->owner = nullptr;
|
||||||
if (is_new)
|
if (is_new)
|
||||||
|
@ -1344,7 +1347,7 @@ namespace Clipper2Lib {
|
||||||
SetSides(*outrec, e2, e1);
|
SetSides(*outrec, e2, e1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OutPt* op = new OutPt(pt, outrec);
|
OutPt* op = new OutPt(pt, outrec);
|
||||||
outrec->pts = op;
|
outrec->pts = op;
|
||||||
return op;
|
return op;
|
||||||
|
@ -1359,7 +1362,7 @@ namespace Clipper2Lib {
|
||||||
SwapFrontBackSides(*e1.outrec);
|
SwapFrontBackSides(*e1.outrec);
|
||||||
else if (IsOpenEnd(e2))
|
else if (IsOpenEnd(e2))
|
||||||
SwapFrontBackSides(*e2.outrec);
|
SwapFrontBackSides(*e2.outrec);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
succeeded_ = false;
|
succeeded_ = false;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -1369,7 +1372,7 @@ namespace Clipper2Lib {
|
||||||
OutPt* result = AddOutPt(e1, pt);
|
OutPt* result = AddOutPt(e1, pt);
|
||||||
if (e1.outrec == e2.outrec)
|
if (e1.outrec == e2.outrec)
|
||||||
{
|
{
|
||||||
OutRec& outrec = *e1.outrec;
|
OutRec& outrec = *e1.outrec;
|
||||||
outrec.pts = result;
|
outrec.pts = result;
|
||||||
|
|
||||||
UncoupleOutRec(e1);
|
UncoupleOutRec(e1);
|
||||||
|
@ -1523,7 +1526,7 @@ namespace Clipper2Lib {
|
||||||
|
|
||||||
void ClipperBase::DoSplitOp(OutRec* outrec, OutPt* splitOp)
|
void ClipperBase::DoSplitOp(OutRec* outrec, OutPt* splitOp)
|
||||||
{
|
{
|
||||||
// splitOp.prev -> splitOp &&
|
// splitOp.prev -> splitOp &&
|
||||||
// splitOp.next -> splitOp.next.next are intersecting
|
// splitOp.next -> splitOp.next.next are intersecting
|
||||||
OutPt* prevOp = splitOp->prev;
|
OutPt* prevOp = splitOp->prev;
|
||||||
OutPt* nextNextOp = splitOp->next->next;
|
OutPt* nextNextOp = splitOp->next->next;
|
||||||
|
@ -1572,7 +1575,7 @@ namespace Clipper2Lib {
|
||||||
SafeDeleteOutPtJoiners(splitOp->next);
|
SafeDeleteOutPtJoiners(splitOp->next);
|
||||||
SafeDeleteOutPtJoiners(splitOp);
|
SafeDeleteOutPtJoiners(splitOp);
|
||||||
|
|
||||||
if (absArea2 >= 1 &&
|
if (absArea2 >= 1 &&
|
||||||
(absArea2 > absArea1 || (area2 > 0) == (area1 > 0)))
|
(absArea2 > absArea1 || (area2 > 0) == (area1 > 0)))
|
||||||
{
|
{
|
||||||
OutRec* newOutRec = new OutRec();
|
OutRec* newOutRec = new OutRec();
|
||||||
|
@ -1762,7 +1765,7 @@ namespace Clipper2Lib {
|
||||||
else result = result->next_in_ael;
|
else result = result->next_in_ael;
|
||||||
}
|
}
|
||||||
result = e->prev_in_ael;
|
result = e->prev_in_ael;
|
||||||
while (result)
|
while (result)
|
||||||
{
|
{
|
||||||
if (result->local_min == e->local_min) return result;
|
if (result->local_min == e->local_min) return result;
|
||||||
else if (!IsHorizontal(*result) && e->bot != result->bot) return nullptr;
|
else if (!IsHorizontal(*result) && e->bot != result->bot) return nullptr;
|
||||||
|
@ -1791,14 +1794,14 @@ namespace Clipper2Lib {
|
||||||
edge_c = &e1;
|
edge_c = &e1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (abs(edge_c->wind_cnt) != 1) return nullptr;
|
if (abs(edge_c->wind_cnt) != 1) return nullptr;
|
||||||
switch (cliptype_)
|
switch (cliptype_)
|
||||||
{
|
{
|
||||||
case ClipType::Union:
|
case ClipType::Union:
|
||||||
if (!IsHotEdge(*edge_c)) return nullptr;
|
if (!IsHotEdge(*edge_c)) return nullptr;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (edge_c->local_min->polytype == PathType::Subject)
|
if (edge_c->local_min->polytype == PathType::Subject)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1821,11 +1824,11 @@ namespace Clipper2Lib {
|
||||||
edge_o->outrec = nullptr;
|
edge_o->outrec = nullptr;
|
||||||
return resultOp;
|
return resultOp;
|
||||||
}
|
}
|
||||||
|
|
||||||
//horizontal edges can pass under open paths at a LocMins
|
//horizontal edges can pass under open paths at a LocMins
|
||||||
else if (pt == edge_o->local_min->vertex->pt &&
|
else if (pt == edge_o->local_min->vertex->pt &&
|
||||||
!IsOpenEnd(*edge_o->local_min->vertex))
|
!IsOpenEnd(*edge_o->local_min->vertex))
|
||||||
{
|
{
|
||||||
//find the other side of the LocMin and
|
//find the other side of the LocMin and
|
||||||
//if it's 'hot' join up with it ...
|
//if it's 'hot' join up with it ...
|
||||||
Active* e3 = FindEdgeWithMatchingLocMin(edge_o);
|
Active* e3 = FindEdgeWithMatchingLocMin(edge_o);
|
||||||
|
@ -1833,7 +1836,7 @@ namespace Clipper2Lib {
|
||||||
{
|
{
|
||||||
edge_o->outrec = e3->outrec;
|
edge_o->outrec = e3->outrec;
|
||||||
if (edge_o->wind_dx > 0)
|
if (edge_o->wind_dx > 0)
|
||||||
SetSides(*e3->outrec, *edge_o, *e3);
|
SetSides(*e3->outrec, *edge_o, *e3);
|
||||||
else
|
else
|
||||||
SetSides(*e3->outrec, *e3, *edge_o);
|
SetSides(*e3->outrec, *e3, *edge_o);
|
||||||
return e3->outrec->pts;
|
return e3->outrec->pts;
|
||||||
|
@ -1847,7 +1850,7 @@ namespace Clipper2Lib {
|
||||||
|
|
||||||
|
|
||||||
//MANAGING CLOSED PATHS FROM HERE ON
|
//MANAGING CLOSED PATHS FROM HERE ON
|
||||||
|
|
||||||
//UPDATE WINDING COUNTS...
|
//UPDATE WINDING COUNTS...
|
||||||
|
|
||||||
int old_e1_windcnt, old_e2_windcnt;
|
int old_e1_windcnt, old_e2_windcnt;
|
||||||
|
@ -1913,7 +1916,7 @@ namespace Clipper2Lib {
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
//NOW PROCESS THE INTERSECTION ...
|
//NOW PROCESS THE INTERSECTION ...
|
||||||
OutPt* resultOp = nullptr;
|
OutPt* resultOp = nullptr;
|
||||||
//if both edges are 'hot' ...
|
//if both edges are 'hot' ...
|
||||||
|
@ -2282,7 +2285,7 @@ namespace Clipper2Lib {
|
||||||
inline bool HorzIsSpike(const Active& horzEdge)
|
inline bool HorzIsSpike(const Active& horzEdge)
|
||||||
{
|
{
|
||||||
Point64 nextPt = NextVertex(horzEdge)->pt;
|
Point64 nextPt = NextVertex(horzEdge)->pt;
|
||||||
return (nextPt.y == horzEdge.bot.y) &&
|
return (nextPt.y == horzEdge.bot.y) &&
|
||||||
(horzEdge.bot.x < horzEdge.top.x) != (horzEdge.top.x < nextPt.x);
|
(horzEdge.bot.x < horzEdge.top.x) != (horzEdge.top.x < nextPt.x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2295,7 +2298,7 @@ namespace Clipper2Lib {
|
||||||
//always trim 180 deg. spikes (in closed paths)
|
//always trim 180 deg. spikes (in closed paths)
|
||||||
//but otherwise break if preserveCollinear = true
|
//but otherwise break if preserveCollinear = true
|
||||||
if (preserveCollinear &&
|
if (preserveCollinear &&
|
||||||
((pt.x < horzEdge.top.x) != (horzEdge.bot.x < horzEdge.top.x)))
|
((pt.x < horzEdge.top.x) != (horzEdge.bot.x < horzEdge.top.x)))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
horzEdge.vertex_top = NextVertex(horzEdge);
|
horzEdge.vertex_top = NextVertex(horzEdge);
|
||||||
|
@ -2353,11 +2356,11 @@ namespace Clipper2Lib {
|
||||||
|
|
||||||
OutPt* op;
|
OutPt* op;
|
||||||
while (true) // loop through consec. horizontal edges
|
while (true) // loop through consec. horizontal edges
|
||||||
{
|
{
|
||||||
if (horzIsOpen && IsMaxima(horz) && !IsOpenEnd(horz))
|
if (horzIsOpen && IsMaxima(horz) && !IsOpenEnd(horz))
|
||||||
{
|
{
|
||||||
vertex_max = GetCurrYMaximaVertex(horz);
|
vertex_max = GetCurrYMaximaVertex(horz);
|
||||||
if (vertex_max)
|
if (vertex_max)
|
||||||
max_pair = GetHorzMaximaPair(horz, vertex_max);
|
max_pair = GetHorzMaximaPair(horz, vertex_max);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2388,7 +2391,7 @@ namespace Clipper2Lib {
|
||||||
|
|
||||||
//if horzEdge is a maxima, keep going until we reach
|
//if horzEdge is a maxima, keep going until we reach
|
||||||
//its maxima pair, otherwise check for break conditions
|
//its maxima pair, otherwise check for break conditions
|
||||||
if (vertex_max != horz.vertex_top || IsOpenEnd(horz))
|
if (vertex_max != horz.vertex_top || IsOpenEnd(horz))
|
||||||
{
|
{
|
||||||
//otherwise stop when 'ae' is beyond the end of the horizontal line
|
//otherwise stop when 'ae' is beyond the end of the horizontal line
|
||||||
if ((is_left_to_right && e->curr_x > horz_right) ||
|
if ((is_left_to_right && e->curr_x > horz_right) ||
|
||||||
|
@ -2467,15 +2470,15 @@ namespace Clipper2Lib {
|
||||||
{
|
{
|
||||||
AddOutPt(horz, horz.top);
|
AddOutPt(horz, horz.top);
|
||||||
if (IsFront(horz))
|
if (IsFront(horz))
|
||||||
horz.outrec->front_edge = nullptr;
|
horz.outrec->front_edge = nullptr;
|
||||||
else
|
else
|
||||||
horz.outrec->back_edge = nullptr;
|
horz.outrec->back_edge = nullptr;
|
||||||
horz.outrec = nullptr;
|
horz.outrec = nullptr;
|
||||||
}
|
}
|
||||||
DeleteFromAEL(horz);
|
DeleteFromAEL(horz);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (NextVertex(horz)->pt.y != horz.top.y)
|
else if (NextVertex(horz)->pt.y != horz.top.y)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//still more horizontals in bound to process ...
|
//still more horizontals in bound to process ...
|
||||||
|
@ -2486,7 +2489,7 @@ namespace Clipper2Lib {
|
||||||
if (PreserveCollinear && !horzIsOpen && HorzIsSpike(horz))
|
if (PreserveCollinear && !horzIsOpen && HorzIsSpike(horz))
|
||||||
TrimHorz(horz, true);
|
TrimHorz(horz, true);
|
||||||
|
|
||||||
is_left_to_right =
|
is_left_to_right =
|
||||||
ResetHorzDirection(horz, max_pair, horz_left, horz_right);
|
ResetHorzDirection(horz, max_pair, horz_left, horz_right);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2499,7 +2502,7 @@ namespace Clipper2Lib {
|
||||||
else
|
else
|
||||||
op = nullptr;
|
op = nullptr;
|
||||||
|
|
||||||
if ((horzIsOpen && !IsOpenEnd(horz)) ||
|
if ((horzIsOpen && !IsOpenEnd(horz)) ||
|
||||||
(!horzIsOpen && vertex_max != horz.vertex_top))
|
(!horzIsOpen && vertex_max != horz.vertex_top))
|
||||||
{
|
{
|
||||||
UpdateEdgeIntoAEL(&horz); // this is the end of an intermediate horiz.
|
UpdateEdgeIntoAEL(&horz); // this is the end of an intermediate horiz.
|
||||||
|
@ -2516,7 +2519,7 @@ namespace Clipper2Lib {
|
||||||
AddJoin(op2, op);
|
AddJoin(op2, op);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (IsHotEdge(horz))
|
else if (IsHotEdge(horz))
|
||||||
AddLocalMaxPoly(horz, *max_pair, horz.top);
|
AddLocalMaxPoly(horz, *max_pair, horz.top);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2966,7 +2969,7 @@ namespace Clipper2Lib {
|
||||||
OutRec* outrec = ProcessJoin(j);
|
OutRec* outrec = ProcessJoin(j);
|
||||||
CleanCollinear(outrec);
|
CleanCollinear(outrec);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
delete j;
|
delete j;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3015,7 +3018,7 @@ namespace Clipper2Lib {
|
||||||
bool CollinearSegsOverlap(const Point64& seg1a, const Point64& seg1b,
|
bool CollinearSegsOverlap(const Point64& seg1a, const Point64& seg1b,
|
||||||
const Point64& seg2a, const Point64& seg2b)
|
const Point64& seg2a, const Point64& seg2b)
|
||||||
{
|
{
|
||||||
//precondition: seg1 and seg2 are collinear
|
//precondition: seg1 and seg2 are collinear
|
||||||
if (seg1a.x == seg1b.x)
|
if (seg1a.x == seg1b.x)
|
||||||
{
|
{
|
||||||
if (seg2a.x != seg1a.x || seg2a.x != seg2b.x) return false;
|
if (seg2a.x != seg1a.x || seg2a.x != seg2b.x) return false;
|
||||||
|
@ -3146,7 +3149,7 @@ namespace Clipper2Lib {
|
||||||
{
|
{
|
||||||
or1->pts = op1;
|
or1->pts = op1;
|
||||||
or2->pts = nullptr;
|
or2->pts = nullptr;
|
||||||
if (or1->owner && (!or2->owner ||
|
if (or1->owner && (!or2->owner ||
|
||||||
or2->owner->idx < or1->owner->idx))
|
or2->owner->idx < or1->owner->idx))
|
||||||
or1->owner = or2->owner;
|
or1->owner = or2->owner;
|
||||||
or2->owner = or1;
|
or2->owner = or1;
|
||||||
|
@ -3156,7 +3159,7 @@ namespace Clipper2Lib {
|
||||||
result = or2;
|
result = or2;
|
||||||
or2->pts = op1;
|
or2->pts = op1;
|
||||||
or1->pts = nullptr;
|
or1->pts = nullptr;
|
||||||
if (or2->owner && (!or1->owner ||
|
if (or2->owner && (!or1->owner ||
|
||||||
or1->owner->idx < or2->owner->idx))
|
or1->owner->idx < or2->owner->idx))
|
||||||
or2->owner = or1->owner;
|
or2->owner = or1->owner;
|
||||||
or1->owner = or2;
|
or1->owner = or2;
|
||||||
|
@ -3207,7 +3210,7 @@ namespace Clipper2Lib {
|
||||||
{
|
{
|
||||||
or1->pts = op1;
|
or1->pts = op1;
|
||||||
or2->pts = nullptr;
|
or2->pts = nullptr;
|
||||||
if (or1->owner && (!or2->owner ||
|
if (or1->owner && (!or2->owner ||
|
||||||
or2->owner->idx < or1->owner->idx))
|
or2->owner->idx < or1->owner->idx))
|
||||||
or1->owner = or2->owner;
|
or1->owner = or2->owner;
|
||||||
or2->owner = or1;
|
or2->owner = or1;
|
||||||
|
@ -3217,9 +3220,9 @@ namespace Clipper2Lib {
|
||||||
result = or2;
|
result = or2;
|
||||||
or2->pts = op1;
|
or2->pts = op1;
|
||||||
or1->pts = nullptr;
|
or1->pts = nullptr;
|
||||||
if (or2->owner && (!or1->owner ||
|
if (or2->owner && (!or1->owner ||
|
||||||
or1->owner->idx < or2->owner->idx))
|
or1->owner->idx < or2->owner->idx))
|
||||||
or2->owner = or1->owner;
|
or2->owner = or1->owner;
|
||||||
or1->owner = or2;
|
or1->owner = or2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3310,11 +3313,11 @@ namespace Clipper2Lib {
|
||||||
if (pt.y > result.bottom) result.bottom = pt.y;
|
if (pt.y > result.bottom) result.bottom = pt.y;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BuildPath64(OutPt* op, bool reverse, bool isOpen, Path64& path)
|
bool BuildPath64(OutPt* op, bool reverse, bool isOpen, Path64& path)
|
||||||
{
|
{
|
||||||
if (op->next == op || (!isOpen && op->next == op->prev))
|
if (op->next == op || (!isOpen && op->next == op->prev))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
path.resize(0);
|
path.resize(0);
|
||||||
|
@ -3355,9 +3358,9 @@ namespace Clipper2Lib {
|
||||||
if (owner->bounds.IsEmpty()) owner->bounds = GetBounds(owner->path);
|
if (owner->bounds.IsEmpty()) owner->bounds = GetBounds(owner->path);
|
||||||
bool is_inside_owner_bounds = owner->bounds.Contains(outrec->bounds);
|
bool is_inside_owner_bounds = owner->bounds.Contains(outrec->bounds);
|
||||||
|
|
||||||
// while looking for the correct owner, check the owner's
|
// while looking for the correct owner, check the owner's
|
||||||
// splits **before** checking the owner itself because
|
// splits **before** checking the owner itself because
|
||||||
// splits can occur internally, and checking the owner
|
// splits can occur internally, and checking the owner
|
||||||
// first would miss the inner split's true ownership
|
// first would miss the inner split's true ownership
|
||||||
if (owner->splits)
|
if (owner->splits)
|
||||||
{
|
{
|
||||||
|
@ -3388,7 +3391,7 @@ namespace Clipper2Lib {
|
||||||
{
|
{
|
||||||
if (is_inside_owner_bounds && Path1InsidePath2(outrec, outrec->owner))
|
if (is_inside_owner_bounds && Path1InsidePath2(outrec, outrec->owner))
|
||||||
return true;
|
return true;
|
||||||
// otherwise keep trying with owner's owner
|
// otherwise keep trying with owner's owner
|
||||||
outrec->owner = outrec->owner->owner;
|
outrec->owner = outrec->owner->owner;
|
||||||
if (!outrec->owner) return true; // true or false
|
if (!outrec->owner) return true; // true or false
|
||||||
is_inside_owner_bounds = outrec->owner->bounds.Contains(outrec->bounds);
|
is_inside_owner_bounds = outrec->owner->bounds.Contains(outrec->bounds);
|
||||||
|
|
Loading…
Reference in New Issue