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