Clipper memory optimization: Own memory manager for OutPt objects.
Allocate OutPt by chunks of 32, reuse the released OutPt objects.
This commit is contained in:
parent
f24427cd76
commit
a9a20003c0
@ -65,14 +65,6 @@ static int const Skip = -2; //edge that would otherwise close a path
|
|||||||
#define TOLERANCE (1.0e-20)
|
#define TOLERANCE (1.0e-20)
|
||||||
#define NEAR_ZERO(val) (((val) > -TOLERANCE) && ((val) < TOLERANCE))
|
#define NEAR_ZERO(val) (((val) > -TOLERANCE) && ((val) < TOLERANCE))
|
||||||
|
|
||||||
// Point of an output polygon.
|
|
||||||
struct OutPt {
|
|
||||||
int Idx;
|
|
||||||
IntPoint Pt;
|
|
||||||
OutPt *Next;
|
|
||||||
OutPt *Prev;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Output polygon.
|
// Output polygon.
|
||||||
struct OutRec {
|
struct OutRec {
|
||||||
int Idx;
|
int Idx;
|
||||||
@ -571,19 +563,6 @@ void ReversePolyPtLinks(OutPt *pp)
|
|||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
void DisposeOutPts(OutPt*& pp)
|
|
||||||
{
|
|
||||||
if (pp == 0) return;
|
|
||||||
pp->Prev->Next = 0;
|
|
||||||
while( pp )
|
|
||||||
{
|
|
||||||
OutPt *tmpPp = pp;
|
|
||||||
pp = pp->Next;
|
|
||||||
delete tmpPp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
inline void InitEdge(TEdge* e, TEdge* eNext, TEdge* ePrev, const IntPoint& Pt)
|
inline void InitEdge(TEdge* e, TEdge* eNext, TEdge* ePrev, const IntPoint& Pt)
|
||||||
{
|
{
|
||||||
std::memset(e, 0, sizeof(TEdge));
|
std::memset(e, 0, sizeof(TEdge));
|
||||||
@ -1219,11 +1198,14 @@ IntRect ClipperBase::GetBounds()
|
|||||||
// TClipper methods ...
|
// TClipper methods ...
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
Clipper::Clipper(int initOptions) : ClipperBase() //constructor
|
Clipper::Clipper(int initOptions) :
|
||||||
|
ClipperBase(),
|
||||||
|
m_OutPtsFree(nullptr),
|
||||||
|
m_OutPtsChunkSize(32),
|
||||||
|
m_OutPtsChunkLast(32),
|
||||||
|
m_ActiveEdges(nullptr),
|
||||||
|
m_SortedEdges(nullptr)
|
||||||
{
|
{
|
||||||
m_ActiveEdges = 0;
|
|
||||||
m_SortedEdges = 0;
|
|
||||||
m_UseFullRange = false;
|
|
||||||
m_ReverseOutput = ((initOptions & ioReverseSolution) != 0);
|
m_ReverseOutput = ((initOptions & ioReverseSolution) != 0);
|
||||||
m_StrictSimple = ((initOptions & ioStrictlySimple) != 0);
|
m_StrictSimple = ((initOptions & ioStrictlySimple) != 0);
|
||||||
m_PreserveCollinear = ((initOptions & ioPreserveCollinear) != 0);
|
m_PreserveCollinear = ((initOptions & ioPreserveCollinear) != 0);
|
||||||
@ -1351,12 +1333,32 @@ bool Clipper::ExecuteInternal()
|
|||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
void Clipper::DisposeAllOutRecs(){
|
OutPt* Clipper::AllocateOutPt()
|
||||||
for (OutRec *outRec : m_PolyOuts) {
|
{
|
||||||
if (outRec->Pts)
|
OutPt *pt;
|
||||||
DisposeOutPts(outRec->Pts);
|
if (m_OutPtsFree) {
|
||||||
delete outRec;
|
// Recycle some of the already released points.
|
||||||
|
pt = m_OutPtsFree;
|
||||||
|
m_OutPtsFree = pt->Next;
|
||||||
|
} else if (m_OutPtsChunkLast < m_OutPtsChunkSize) {
|
||||||
|
// Get a point from the last chunk.
|
||||||
|
pt = m_OutPts.back() + (m_OutPtsChunkLast ++);
|
||||||
|
} else {
|
||||||
|
// The last chunk is full. Allocate a new one.
|
||||||
|
m_OutPts.push_back(new OutPt[m_OutPtsChunkSize]);
|
||||||
|
m_OutPtsChunkLast = 1;
|
||||||
|
pt = m_OutPts.back();
|
||||||
}
|
}
|
||||||
|
return pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Clipper::DisposeAllOutRecs()
|
||||||
|
{
|
||||||
|
for (OutPt *pts : m_OutPts)
|
||||||
|
delete[] pts;
|
||||||
|
m_OutPts.clear();
|
||||||
|
m_OutPtsFree = nullptr;
|
||||||
|
m_OutPtsChunkLast = m_OutPtsChunkSize;
|
||||||
m_PolyOuts.clear();
|
m_PolyOuts.clear();
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@ -2156,7 +2158,7 @@ OutPt* Clipper::AddOutPt(TEdge *e, const IntPoint &pt)
|
|||||||
{
|
{
|
||||||
OutRec *outRec = CreateOutRec();
|
OutRec *outRec = CreateOutRec();
|
||||||
outRec->IsOpen = (e->WindDelta == 0);
|
outRec->IsOpen = (e->WindDelta == 0);
|
||||||
OutPt* newOp = new OutPt;
|
OutPt* newOp = this->AllocateOutPt();
|
||||||
outRec->Pts = newOp;
|
outRec->Pts = newOp;
|
||||||
newOp->Idx = outRec->Idx;
|
newOp->Idx = outRec->Idx;
|
||||||
newOp->Pt = pt;
|
newOp->Pt = pt;
|
||||||
@ -2176,7 +2178,7 @@ OutPt* Clipper::AddOutPt(TEdge *e, const IntPoint &pt)
|
|||||||
if (ToFront && (pt == op->Pt)) return op;
|
if (ToFront && (pt == op->Pt)) return op;
|
||||||
else if (!ToFront && (pt == op->Prev->Pt)) return op->Prev;
|
else if (!ToFront && (pt == op->Prev->Pt)) return op->Prev;
|
||||||
|
|
||||||
OutPt* newOp = new OutPt;
|
OutPt* newOp = this->AllocateOutPt();
|
||||||
newOp->Idx = outRec->Idx;
|
newOp->Idx = outRec->Idx;
|
||||||
newOp->Pt = pt;
|
newOp->Pt = pt;
|
||||||
newOp->Next = op;
|
newOp->Next = op;
|
||||||
@ -2843,14 +2845,14 @@ void Clipper::FixupOutPolyline(OutRec &outrec)
|
|||||||
OutPt *tmpPP = pp->Prev;
|
OutPt *tmpPP = pp->Prev;
|
||||||
tmpPP->Next = pp->Next;
|
tmpPP->Next = pp->Next;
|
||||||
pp->Next->Prev = tmpPP;
|
pp->Next->Prev = tmpPP;
|
||||||
delete pp;
|
this->DisposeOutPt(pp);
|
||||||
pp = tmpPP;
|
pp = tmpPP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pp == pp->Prev)
|
if (pp == pp->Prev)
|
||||||
{
|
{
|
||||||
DisposeOutPts(pp);
|
this->DisposeOutPts(pp);
|
||||||
outrec.Pts = 0;
|
outrec.Pts = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -2871,7 +2873,7 @@ void Clipper::FixupOutPolygon(OutRec &outrec)
|
|||||||
if (pp->Prev == pp || pp->Prev == pp->Next)
|
if (pp->Prev == pp || pp->Prev == pp->Next)
|
||||||
{
|
{
|
||||||
// Empty loop or a stick. Release the polygon.
|
// Empty loop or a stick. Release the polygon.
|
||||||
DisposeOutPts(pp);
|
this->DisposeOutPts(pp);
|
||||||
outrec.Pts = nullptr;
|
outrec.Pts = nullptr;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -2886,7 +2888,7 @@ void Clipper::FixupOutPolygon(OutRec &outrec)
|
|||||||
pp->Prev->Next = pp->Next;
|
pp->Prev->Next = pp->Next;
|
||||||
pp->Next->Prev = pp->Prev;
|
pp->Next->Prev = pp->Prev;
|
||||||
pp = pp->Prev;
|
pp = pp->Prev;
|
||||||
delete tmp;
|
this->DisposeOutPt(tmp);
|
||||||
}
|
}
|
||||||
else if (pp == lastOK) break;
|
else if (pp == lastOK) break;
|
||||||
else
|
else
|
||||||
@ -3063,9 +3065,9 @@ void Clipper::InsertEdgeIntoAEL(TEdge *edge, TEdge* startEdge)
|
|||||||
}
|
}
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
OutPt* DupOutPt(OutPt* outPt, bool InsertAfter)
|
OutPt* Clipper::DupOutPt(OutPt* outPt, bool InsertAfter)
|
||||||
{
|
{
|
||||||
OutPt* result = new OutPt;
|
OutPt* result = this->AllocateOutPt();
|
||||||
result->Pt = outPt->Pt;
|
result->Pt = outPt->Pt;
|
||||||
result->Idx = outPt->Idx;
|
result->Idx = outPt->Idx;
|
||||||
if (InsertAfter)
|
if (InsertAfter)
|
||||||
@ -3086,7 +3088,7 @@ OutPt* DupOutPt(OutPt* outPt, bool InsertAfter)
|
|||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
bool JoinHorz(OutPt* op1, OutPt* op1b, OutPt* op2, OutPt* op2b,
|
bool Clipper::JoinHorz(OutPt* op1, OutPt* op1b, OutPt* op2, OutPt* op2b,
|
||||||
const IntPoint &Pt, bool DiscardLeft)
|
const IntPoint &Pt, bool DiscardLeft)
|
||||||
{
|
{
|
||||||
Direction Dir1 = (op1->Pt.X > op1b->Pt.X ? dRightToLeft : dLeftToRight);
|
Direction Dir1 = (op1->Pt.X > op1b->Pt.X ? dRightToLeft : dLeftToRight);
|
||||||
@ -3104,12 +3106,12 @@ bool JoinHorz(OutPt* op1, OutPt* op1b, OutPt* op2, OutPt* op2b,
|
|||||||
op1->Next->Pt.X >= op1->Pt.X && op1->Next->Pt.Y == Pt.Y)
|
op1->Next->Pt.X >= op1->Pt.X && op1->Next->Pt.Y == Pt.Y)
|
||||||
op1 = op1->Next;
|
op1 = op1->Next;
|
||||||
if (DiscardLeft && (op1->Pt.X != Pt.X)) op1 = op1->Next;
|
if (DiscardLeft && (op1->Pt.X != Pt.X)) op1 = op1->Next;
|
||||||
op1b = DupOutPt(op1, !DiscardLeft);
|
op1b = this->DupOutPt(op1, !DiscardLeft);
|
||||||
if (op1b->Pt != Pt)
|
if (op1b->Pt != Pt)
|
||||||
{
|
{
|
||||||
op1 = op1b;
|
op1 = op1b;
|
||||||
op1->Pt = Pt;
|
op1->Pt = Pt;
|
||||||
op1b = DupOutPt(op1, !DiscardLeft);
|
op1b = this->DupOutPt(op1, !DiscardLeft);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -3118,12 +3120,12 @@ bool JoinHorz(OutPt* op1, OutPt* op1b, OutPt* op2, OutPt* op2b,
|
|||||||
op1->Next->Pt.X <= op1->Pt.X && op1->Next->Pt.Y == Pt.Y)
|
op1->Next->Pt.X <= op1->Pt.X && op1->Next->Pt.Y == Pt.Y)
|
||||||
op1 = op1->Next;
|
op1 = op1->Next;
|
||||||
if (!DiscardLeft && (op1->Pt.X != Pt.X)) op1 = op1->Next;
|
if (!DiscardLeft && (op1->Pt.X != Pt.X)) op1 = op1->Next;
|
||||||
op1b = DupOutPt(op1, DiscardLeft);
|
op1b = this->DupOutPt(op1, DiscardLeft);
|
||||||
if (op1b->Pt != Pt)
|
if (op1b->Pt != Pt)
|
||||||
{
|
{
|
||||||
op1 = op1b;
|
op1 = op1b;
|
||||||
op1->Pt = Pt;
|
op1->Pt = Pt;
|
||||||
op1b = DupOutPt(op1, DiscardLeft);
|
op1b = this->DupOutPt(op1, DiscardLeft);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3133,12 +3135,12 @@ bool JoinHorz(OutPt* op1, OutPt* op1b, OutPt* op2, OutPt* op2b,
|
|||||||
op2->Next->Pt.X >= op2->Pt.X && op2->Next->Pt.Y == Pt.Y)
|
op2->Next->Pt.X >= op2->Pt.X && op2->Next->Pt.Y == Pt.Y)
|
||||||
op2 = op2->Next;
|
op2 = op2->Next;
|
||||||
if (DiscardLeft && (op2->Pt.X != Pt.X)) op2 = op2->Next;
|
if (DiscardLeft && (op2->Pt.X != Pt.X)) op2 = op2->Next;
|
||||||
op2b = DupOutPt(op2, !DiscardLeft);
|
op2b = this->DupOutPt(op2, !DiscardLeft);
|
||||||
if (op2b->Pt != Pt)
|
if (op2b->Pt != Pt)
|
||||||
{
|
{
|
||||||
op2 = op2b;
|
op2 = op2b;
|
||||||
op2->Pt = Pt;
|
op2->Pt = Pt;
|
||||||
op2b = DupOutPt(op2, !DiscardLeft);
|
op2b = this->DupOutPt(op2, !DiscardLeft);
|
||||||
};
|
};
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
@ -3146,12 +3148,12 @@ bool JoinHorz(OutPt* op1, OutPt* op1b, OutPt* op2, OutPt* op2b,
|
|||||||
op2->Next->Pt.X <= op2->Pt.X && op2->Next->Pt.Y == Pt.Y)
|
op2->Next->Pt.X <= op2->Pt.X && op2->Next->Pt.Y == Pt.Y)
|
||||||
op2 = op2->Next;
|
op2 = op2->Next;
|
||||||
if (!DiscardLeft && (op2->Pt.X != Pt.X)) op2 = op2->Next;
|
if (!DiscardLeft && (op2->Pt.X != Pt.X)) op2 = op2->Next;
|
||||||
op2b = DupOutPt(op2, DiscardLeft);
|
op2b = this->DupOutPt(op2, DiscardLeft);
|
||||||
if (op2b->Pt != Pt)
|
if (op2b->Pt != Pt)
|
||||||
{
|
{
|
||||||
op2 = op2b;
|
op2 = op2b;
|
||||||
op2->Pt = Pt;
|
op2->Pt = Pt;
|
||||||
op2b = DupOutPt(op2, DiscardLeft);
|
op2b = this->DupOutPt(op2, DiscardLeft);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -3203,8 +3205,8 @@ bool Clipper::JoinPoints(Join *j, OutRec* outRec1, OutRec* outRec2)
|
|||||||
if (reverse1 == reverse2) return false;
|
if (reverse1 == reverse2) return false;
|
||||||
if (reverse1)
|
if (reverse1)
|
||||||
{
|
{
|
||||||
op1b = DupOutPt(op1, false);
|
op1b = this->DupOutPt(op1, false);
|
||||||
op2b = DupOutPt(op2, true);
|
op2b = this->DupOutPt(op2, true);
|
||||||
op1->Prev = op2;
|
op1->Prev = op2;
|
||||||
op2->Next = op1;
|
op2->Next = op1;
|
||||||
op1b->Next = op2b;
|
op1b->Next = op2b;
|
||||||
@ -3214,8 +3216,8 @@ bool Clipper::JoinPoints(Join *j, OutRec* outRec1, OutRec* outRec2)
|
|||||||
return true;
|
return true;
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
op1b = DupOutPt(op1, true);
|
op1b = this->DupOutPt(op1, true);
|
||||||
op2b = DupOutPt(op2, false);
|
op2b = this->DupOutPt(op2, false);
|
||||||
op1->Next = op2;
|
op1->Next = op2;
|
||||||
op2->Prev = op1;
|
op2->Prev = op1;
|
||||||
op1b->Prev = op2b;
|
op1b->Prev = op2b;
|
||||||
@ -3307,8 +3309,8 @@ bool Clipper::JoinPoints(Join *j, OutRec* outRec1, OutRec* outRec2)
|
|||||||
|
|
||||||
if (Reverse1)
|
if (Reverse1)
|
||||||
{
|
{
|
||||||
op1b = DupOutPt(op1, false);
|
op1b = this->DupOutPt(op1, false);
|
||||||
op2b = DupOutPt(op2, true);
|
op2b = this->DupOutPt(op2, true);
|
||||||
op1->Prev = op2;
|
op1->Prev = op2;
|
||||||
op2->Next = op1;
|
op2->Next = op1;
|
||||||
op1b->Next = op2b;
|
op1b->Next = op2b;
|
||||||
@ -3318,8 +3320,8 @@ bool Clipper::JoinPoints(Join *j, OutRec* outRec1, OutRec* outRec2)
|
|||||||
return true;
|
return true;
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
op1b = DupOutPt(op1, true);
|
op1b = this->DupOutPt(op1, true);
|
||||||
op2b = DupOutPt(op2, false);
|
op2b = this->DupOutPt(op2, false);
|
||||||
op1->Next = op2;
|
op1->Next = op2;
|
||||||
op2->Prev = op1;
|
op2->Prev = op1;
|
||||||
op1b->Prev = op2b;
|
op1b->Prev = op2b;
|
||||||
|
@ -261,7 +261,20 @@ enum EdgeSide { esLeft = 1, esRight = 2};
|
|||||||
TEdge *RightBound;
|
TEdge *RightBound;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct OutPt;
|
// Point of an output polygon.
|
||||||
|
// 36B on 64bit system with not use_int32 and not use_xyz.
|
||||||
|
struct OutPt {
|
||||||
|
// 4B
|
||||||
|
int Idx;
|
||||||
|
// 8B (if use_int32 and not use_xyz) or 16B (if not use_int32 and not use_xyz)
|
||||||
|
// or 12B (if use_int32 and use_xyz) or 24B (if not use_int32 and use_xyz)
|
||||||
|
IntPoint Pt;
|
||||||
|
// 4B on 32bit system, 8B on 64bit system
|
||||||
|
OutPt *Next;
|
||||||
|
// 4B on 32bit system, 8B on 64bit system
|
||||||
|
OutPt *Prev;
|
||||||
|
};
|
||||||
|
|
||||||
struct OutRec;
|
struct OutRec;
|
||||||
struct Join {
|
struct Join {
|
||||||
Join(OutPt *OutPt1, OutPt *OutPt2, IntPoint OffPt) :
|
Join(OutPt *OutPt1, OutPt *OutPt2, IntPoint OffPt) :
|
||||||
@ -318,6 +331,7 @@ class Clipper : public virtual ClipperBase
|
|||||||
public:
|
public:
|
||||||
Clipper(int initOptions = 0);
|
Clipper(int initOptions = 0);
|
||||||
~Clipper() { Clear(); }
|
~Clipper() { Clear(); }
|
||||||
|
void Clear() { ClipperBase::Clear(); DisposeAllOutRecs(); }
|
||||||
bool Execute(ClipType clipType,
|
bool Execute(ClipType clipType,
|
||||||
Paths &solution,
|
Paths &solution,
|
||||||
PolyFillType fillType = pftEvenOdd)
|
PolyFillType fillType = pftEvenOdd)
|
||||||
@ -346,25 +360,34 @@ protected:
|
|||||||
void Reset();
|
void Reset();
|
||||||
virtual bool ExecuteInternal();
|
virtual bool ExecuteInternal();
|
||||||
private:
|
private:
|
||||||
std::vector<OutRec*> m_PolyOuts;
|
|
||||||
std::vector<Join> m_Joins;
|
// Output polygons.
|
||||||
std::vector<Join> m_GhostJoins;
|
std::vector<OutRec*> m_PolyOuts;
|
||||||
|
// Output points, allocated by a continuous sets of m_OutPtsChunkSize.
|
||||||
|
std::vector<OutPt*> m_OutPts;
|
||||||
|
// List of free output points, to be used before taking a point from m_OutPts or allocating a new chunk.
|
||||||
|
OutPt *m_OutPtsFree;
|
||||||
|
size_t m_OutPtsChunkSize;
|
||||||
|
size_t m_OutPtsChunkLast;
|
||||||
|
|
||||||
|
std::vector<Join> m_Joins;
|
||||||
|
std::vector<Join> m_GhostJoins;
|
||||||
std::vector<IntersectNode> m_IntersectList;
|
std::vector<IntersectNode> m_IntersectList;
|
||||||
ClipType m_ClipType;
|
ClipType m_ClipType;
|
||||||
// A priority queue (a binary heap) of Y coordinates.
|
// A priority queue (a binary heap) of Y coordinates.
|
||||||
std::priority_queue<cInt> m_Scanbeam;
|
std::priority_queue<cInt> m_Scanbeam;
|
||||||
// Maxima are collected by ProcessEdgesAtTopOfScanbeam(), consumed by ProcessHorizontal().
|
// Maxima are collected by ProcessEdgesAtTopOfScanbeam(), consumed by ProcessHorizontal().
|
||||||
std::vector<cInt> m_Maxima;
|
std::vector<cInt> m_Maxima;
|
||||||
TEdge *m_ActiveEdges;
|
TEdge *m_ActiveEdges;
|
||||||
TEdge *m_SortedEdges;
|
TEdge *m_SortedEdges;
|
||||||
PolyFillType m_ClipFillType;
|
PolyFillType m_ClipFillType;
|
||||||
PolyFillType m_SubjFillType;
|
PolyFillType m_SubjFillType;
|
||||||
bool m_ReverseOutput;
|
bool m_ReverseOutput;
|
||||||
// Does the result go to a PolyTree or Paths?
|
// Does the result go to a PolyTree or Paths?
|
||||||
bool m_UsingPolyTree;
|
bool m_UsingPolyTree;
|
||||||
bool m_StrictSimple;
|
bool m_StrictSimple;
|
||||||
#ifdef use_xyz
|
#ifdef use_xyz
|
||||||
ZFillCallback m_ZFill; //custom callback
|
ZFillCallback m_ZFill; //custom callback
|
||||||
#endif
|
#endif
|
||||||
void SetWindingCount(TEdge& edge) const;
|
void SetWindingCount(TEdge& edge) const;
|
||||||
bool IsEvenOddFillType(const TEdge& edge) const
|
bool IsEvenOddFillType(const TEdge& edge) const
|
||||||
@ -393,6 +416,11 @@ private:
|
|||||||
OutRec* CreateOutRec();
|
OutRec* CreateOutRec();
|
||||||
OutPt* AddOutPt(TEdge *e, const IntPoint &pt);
|
OutPt* AddOutPt(TEdge *e, const IntPoint &pt);
|
||||||
OutPt* GetLastOutPt(TEdge *e);
|
OutPt* GetLastOutPt(TEdge *e);
|
||||||
|
OutPt* AllocateOutPt();
|
||||||
|
OutPt* DupOutPt(OutPt* outPt, bool InsertAfter);
|
||||||
|
// Add the point to a list of free points.
|
||||||
|
void DisposeOutPt(OutPt *pt) { pt->Next = m_OutPtsFree; m_OutPtsFree = pt; }
|
||||||
|
void DisposeOutPts(OutPt*& pp) { if (pp != nullptr) { pp->Prev->Next = m_OutPtsFree; m_OutPtsFree = pp; } }
|
||||||
void DisposeAllOutRecs();
|
void DisposeAllOutRecs();
|
||||||
bool ProcessIntersections(const cInt topY);
|
bool ProcessIntersections(const cInt topY);
|
||||||
void BuildIntersectList(const cInt topY);
|
void BuildIntersectList(const cInt topY);
|
||||||
@ -406,6 +434,7 @@ private:
|
|||||||
bool FindOwnerFromSplitRecs(OutRec &outRec, OutRec *&currOrfl);
|
bool FindOwnerFromSplitRecs(OutRec &outRec, OutRec *&currOrfl);
|
||||||
void FixHoleLinkage(OutRec &outrec);
|
void FixHoleLinkage(OutRec &outrec);
|
||||||
bool JoinPoints(Join *j, OutRec* outRec1, OutRec* outRec2);
|
bool JoinPoints(Join *j, OutRec* outRec1, OutRec* outRec2);
|
||||||
|
bool JoinHorz(OutPt* op1, OutPt* op1b, OutPt* op2, OutPt* op2b, const IntPoint &Pt, bool DiscardLeft);
|
||||||
void JoinCommonEdges();
|
void JoinCommonEdges();
|
||||||
void DoSimplePolygons();
|
void DoSimplePolygons();
|
||||||
void FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec) const;
|
void FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec) const;
|
||||||
|
Loading…
Reference in New Issue
Block a user