Another Clipper optimization. When adding a set of paths
to Clipper, allocate the edges in a single continuous vector.
This commit is contained in:
parent
fa4df36963
commit
f24427cd76
2 changed files with 68 additions and 21 deletions
|
@ -896,6 +896,72 @@ TEdge* ClipperBase::ProcessBound(TEdge* E, bool NextIsForward)
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed)
|
bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed)
|
||||||
|
{
|
||||||
|
PROFILE_FUNC();
|
||||||
|
// Remove duplicate end point from a closed input path.
|
||||||
|
// Remove duplicate points from the end of the input path.
|
||||||
|
int highI = (int)pg.size() -1;
|
||||||
|
if (Closed)
|
||||||
|
while (highI > 0 && (pg[highI] == pg[0]))
|
||||||
|
--highI;
|
||||||
|
while (highI > 0 && (pg[highI] == pg[highI -1]))
|
||||||
|
--highI;
|
||||||
|
if ((Closed && highI < 2) || (!Closed && highI < 1))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Allocate a new edge array.
|
||||||
|
std::vector<TEdge> edges(highI + 1);
|
||||||
|
// Fill in the edge array.
|
||||||
|
bool result = AddPathInternal(pg, highI, PolyTyp, Closed, edges.data());
|
||||||
|
if (result)
|
||||||
|
// Success, remember the edge array.
|
||||||
|
m_edges.emplace_back(std::move(edges));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ClipperBase::AddPaths(const Paths &ppg, PolyType PolyTyp, bool Closed)
|
||||||
|
{
|
||||||
|
PROFILE_FUNC();
|
||||||
|
std::vector<int> num_edges(ppg.size(), 0);
|
||||||
|
int num_edges_total = 0;
|
||||||
|
for (size_t i = 0; i < ppg.size(); ++ i) {
|
||||||
|
const Path &pg = ppg[i];
|
||||||
|
// Remove duplicate end point from a closed input path.
|
||||||
|
// Remove duplicate points from the end of the input path.
|
||||||
|
int highI = (int)pg.size() -1;
|
||||||
|
if (Closed)
|
||||||
|
while (highI > 0 && (pg[highI] == pg[0]))
|
||||||
|
--highI;
|
||||||
|
while (highI > 0 && (pg[highI] == pg[highI -1]))
|
||||||
|
--highI;
|
||||||
|
if ((Closed && highI < 2) || (!Closed && highI < 1))
|
||||||
|
highI = -1;
|
||||||
|
num_edges[i] = highI + 1;
|
||||||
|
num_edges_total += highI + 1;
|
||||||
|
}
|
||||||
|
if (num_edges_total == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Allocate a new edge array.
|
||||||
|
std::vector<TEdge> edges(num_edges_total);
|
||||||
|
// Fill in the edge array.
|
||||||
|
bool result = false;
|
||||||
|
TEdge *p_edge = edges.data();
|
||||||
|
for (Paths::size_type i = 0; i < ppg.size(); ++i)
|
||||||
|
if (num_edges[i]) {
|
||||||
|
bool res = AddPathInternal(ppg[i], num_edges[i] - 1, PolyTyp, Closed, p_edge);
|
||||||
|
if (res) {
|
||||||
|
p_edge += num_edges[i];
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (result)
|
||||||
|
// At least some edges were generated. Remember the edge array.
|
||||||
|
m_edges.emplace_back(std::move(edges));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ClipperBase::AddPathInternal(const Path &pg, int highI, PolyType PolyTyp, bool Closed, TEdge* edges)
|
||||||
{
|
{
|
||||||
PROFILE_FUNC();
|
PROFILE_FUNC();
|
||||||
#ifdef use_lines
|
#ifdef use_lines
|
||||||
|
@ -906,15 +972,7 @@ bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed)
|
||||||
throw clipperException("AddPath: Open paths have been disabled.");
|
throw clipperException("AddPath: Open paths have been disabled.");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Remove duplicate end point from a closed input path.
|
assert(highI >= 0 && highI < pg.size());
|
||||||
// Remove duplicate points from the end of the input path.
|
|
||||||
int highI = (int)pg.size() -1;
|
|
||||||
if (Closed) while (highI > 0 && (pg[highI] == pg[0])) --highI;
|
|
||||||
while (highI > 0 && (pg[highI] == pg[highI -1])) --highI;
|
|
||||||
if ((Closed && highI < 2) || (!Closed && highI < 1)) return false;
|
|
||||||
|
|
||||||
//create a new edge array ...
|
|
||||||
std::vector<TEdge> edges(highI + 1);
|
|
||||||
|
|
||||||
//1. Basic (first) edge initialization ...
|
//1. Basic (first) edge initialization ...
|
||||||
try
|
try
|
||||||
|
@ -1018,11 +1076,9 @@ bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed)
|
||||||
E = E->Next;
|
E = E->Next;
|
||||||
}
|
}
|
||||||
m_MinimaList.push_back(locMin);
|
m_MinimaList.push_back(locMin);
|
||||||
m_edges.emplace_back(std::move(edges));
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_edges.emplace_back(std::move(edges));
|
|
||||||
bool leftBoundIsForward;
|
bool leftBoundIsForward;
|
||||||
TEdge* EMin = 0;
|
TEdge* EMin = 0;
|
||||||
|
|
||||||
|
@ -1079,16 +1135,6 @@ bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed)
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
bool ClipperBase::AddPaths(const Paths &ppg, PolyType PolyTyp, bool Closed)
|
|
||||||
{
|
|
||||||
PROFILE_FUNC();
|
|
||||||
bool result = false;
|
|
||||||
for (Paths::size_type i = 0; i < ppg.size(); ++i)
|
|
||||||
if (AddPath(ppg[i], PolyTyp, Closed)) result = true;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void ClipperBase::Clear()
|
void ClipperBase::Clear()
|
||||||
{
|
{
|
||||||
PROFILE_FUNC();
|
PROFILE_FUNC();
|
||||||
|
|
|
@ -291,6 +291,7 @@ public:
|
||||||
bool PreserveCollinear() const {return m_PreserveCollinear;};
|
bool PreserveCollinear() const {return m_PreserveCollinear;};
|
||||||
void PreserveCollinear(bool value) {m_PreserveCollinear = value;};
|
void PreserveCollinear(bool value) {m_PreserveCollinear = value;};
|
||||||
protected:
|
protected:
|
||||||
|
bool AddPathInternal(const Path &pg, int highI, PolyType PolyTyp, bool Closed, TEdge* edges);
|
||||||
TEdge* AddBoundsToLML(TEdge *e, bool IsClosed);
|
TEdge* AddBoundsToLML(TEdge *e, bool IsClosed);
|
||||||
virtual void Reset();
|
virtual void Reset();
|
||||||
TEdge* ProcessBound(TEdge* E, bool IsClockwise);
|
TEdge* ProcessBound(TEdge* E, bool IsClockwise);
|
||||||
|
|
Loading…
Reference in a new issue