libarea: fixed memory leak in CAreaOrderer
This commit is contained in:
parent
2c249e8356
commit
298ad1eb26
|
@ -92,33 +92,22 @@ void CArea::Reorder()
|
||||||
// returns 1, if the curves are overlapping
|
// returns 1, if the curves are overlapping
|
||||||
|
|
||||||
CAreaOrderer ao;
|
CAreaOrderer ao;
|
||||||
std::list<CCurve>::iterator ItLast = m_curves.end();
|
for(std::list<CCurve>::iterator It = m_curves.begin(), ItNext=It; It != m_curves.end(); It=ItNext)
|
||||||
for(std::list<CCurve>::iterator It = m_curves.begin(); It != m_curves.end(); ++It)
|
|
||||||
{
|
{
|
||||||
|
++ItNext;
|
||||||
CCurve& curve = *It;
|
CCurve& curve = *It;
|
||||||
if(!It->IsClosed())
|
if(!It->IsClosed())
|
||||||
continue;
|
continue;
|
||||||
ItLast = It;
|
ao.Insert(make_shared<CCurve>(curve));
|
||||||
ao.Insert(&curve);
|
|
||||||
if(m_set_processing_length_in_split)
|
if(m_set_processing_length_in_split)
|
||||||
{
|
{
|
||||||
CArea::m_processing_done += (m_split_processing_length / m_curves.size());
|
CArea::m_processing_done += (m_split_processing_length / m_curves.size());
|
||||||
}
|
}
|
||||||
|
m_curves.erase(It);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ItLast == m_curves.end())
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(ao.m_top_level)
|
if(ao.m_top_level)
|
||||||
ao.m_top_level->GetArea(*this);
|
ao.m_top_level->GetArea(*this);
|
||||||
|
|
||||||
++ItLast;
|
|
||||||
for(std::list<CCurve>::iterator It=m_curves.begin(), ItNext=It; It!=ItLast; It=ItNext)
|
|
||||||
{
|
|
||||||
++ItNext;
|
|
||||||
if(It->IsClosed())
|
|
||||||
m_curves.erase(It);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class ZigZag
|
class ZigZag
|
||||||
|
|
|
@ -30,29 +30,27 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "AreaOrderer.h"
|
#include "AreaOrderer.h"
|
||||||
#include "Area.h"
|
#include "Area.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
CAreaOrderer* CInnerCurves::area_orderer = NULL;
|
CAreaOrderer* CInnerCurves::area_orderer = NULL;
|
||||||
|
|
||||||
CInnerCurves::CInnerCurves(CInnerCurves* pOuter, const CCurve* curve)
|
CInnerCurves::CInnerCurves(shared_ptr<CInnerCurves> pOuter, shared_ptr<CCurve> curve)
|
||||||
|
:m_pOuter(pOuter)
|
||||||
|
,m_curve(curve)
|
||||||
{
|
{
|
||||||
m_pOuter = pOuter;
|
|
||||||
m_curve = curve;
|
|
||||||
m_unite_area = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CInnerCurves::~CInnerCurves()
|
CInnerCurves::~CInnerCurves()
|
||||||
{
|
{
|
||||||
delete m_unite_area;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CInnerCurves::Insert(const CCurve* pcurve)
|
void CInnerCurves::Insert(shared_ptr<CCurve> pcurve)
|
||||||
{
|
{
|
||||||
std::list<CInnerCurves*> outside_of_these;
|
std::list<shared_ptr<CInnerCurves> > outside_of_these;
|
||||||
std::list<CInnerCurves*> crossing_these;
|
std::list<shared_ptr<CInnerCurves> > crossing_these;
|
||||||
|
|
||||||
// check all inner curves
|
// check all inner curves
|
||||||
for(std::set<CInnerCurves*>::iterator It = m_inner_curves.begin(); It != m_inner_curves.end(); It++)
|
for(shared_ptr<CInnerCurves> c : m_inner_curves) {
|
||||||
{
|
|
||||||
CInnerCurves* c = *It;
|
|
||||||
|
|
||||||
switch(GetOverlapType(*pcurve, *(c->m_curve)))
|
switch(GetOverlapType(*pcurve, *(c->m_curve)))
|
||||||
{
|
{
|
||||||
|
@ -75,28 +73,24 @@ void CInnerCurves::Insert(const CCurve* pcurve)
|
||||||
}
|
}
|
||||||
|
|
||||||
// add as a new inner
|
// add as a new inner
|
||||||
CInnerCurves* new_item = new CInnerCurves(this, pcurve);
|
shared_ptr<CInnerCurves> new_item(new CInnerCurves(shared_from_this(), pcurve));
|
||||||
this->m_inner_curves.insert(new_item);
|
this->m_inner_curves.insert(new_item);
|
||||||
|
|
||||||
for(std::list<CInnerCurves*>::iterator It = outside_of_these.begin(); It != outside_of_these.end(); It++)
|
for(shared_ptr<CInnerCurves> c : outside_of_these) {
|
||||||
{
|
|
||||||
// move items
|
// move items
|
||||||
CInnerCurves* c = *It;
|
|
||||||
c->m_pOuter = new_item;
|
c->m_pOuter = new_item;
|
||||||
new_item->m_inner_curves.insert(c);
|
new_item->m_inner_curves.insert(c);
|
||||||
this->m_inner_curves.erase(c);
|
this->m_inner_curves.erase(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(std::list<CInnerCurves*>::iterator It = crossing_these.begin(); It != crossing_these.end(); It++)
|
for(shared_ptr<CInnerCurves> c : crossing_these) {
|
||||||
{
|
|
||||||
// unite these
|
// unite these
|
||||||
CInnerCurves* c = *It;
|
|
||||||
new_item->Unite(c);
|
new_item->Unite(c);
|
||||||
this->m_inner_curves.erase(c);
|
this->m_inner_curves.erase(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CInnerCurves::GetArea(CArea &area, bool outside, bool use_curve)const
|
void CInnerCurves::GetArea(CArea &area, bool outside, bool use_curve)
|
||||||
{
|
{
|
||||||
if(use_curve && m_curve)
|
if(use_curve && m_curve)
|
||||||
{
|
{
|
||||||
|
@ -104,11 +98,9 @@ void CInnerCurves::GetArea(CArea &area, bool outside, bool use_curve)const
|
||||||
outside = !outside;
|
outside = !outside;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::list<const CInnerCurves*> do_after;
|
std::list<shared_ptr<CInnerCurves> > do_after;
|
||||||
|
|
||||||
for(std::set<CInnerCurves*>::const_iterator It = m_inner_curves.begin(); It != m_inner_curves.end(); It++)
|
for(shared_ptr<CInnerCurves> c: m_inner_curves) {
|
||||||
{
|
|
||||||
const CInnerCurves* c = *It;
|
|
||||||
area.m_curves.push_back(*c->m_curve);
|
area.m_curves.push_back(*c->m_curve);
|
||||||
if(!outside)area.m_curves.back().Reverse();
|
if(!outside)area.m_curves.back().Reverse();
|
||||||
|
|
||||||
|
@ -116,19 +108,15 @@ void CInnerCurves::GetArea(CArea &area, bool outside, bool use_curve)const
|
||||||
else do_after.push_back(c);
|
else do_after.push_back(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(std::list<const CInnerCurves*>::iterator It = do_after.begin(); It != do_after.end(); It++)
|
for(shared_ptr<CInnerCurves> c : do_after)
|
||||||
{
|
|
||||||
const CInnerCurves* c = *It;
|
|
||||||
c->GetArea(area, !outside, false);
|
c->GetArea(area, !outside, false);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CInnerCurves::Unite(const CInnerCurves* c)
|
void CInnerCurves::Unite(shared_ptr<CInnerCurves> c)
|
||||||
{
|
{
|
||||||
// unite all the curves in c, with this one
|
// unite all the curves in c, with this one
|
||||||
CArea* new_area = new CArea();
|
shared_ptr<CArea> new_area(new CArea());
|
||||||
new_area->m_curves.push_back(*m_curve);
|
new_area->m_curves.push_back(*m_curve);
|
||||||
delete m_unite_area;
|
|
||||||
m_unite_area = new_area;
|
m_unite_area = new_area;
|
||||||
|
|
||||||
CArea a2;
|
CArea a2;
|
||||||
|
@ -140,21 +128,21 @@ void CInnerCurves::Unite(const CInnerCurves* c)
|
||||||
{
|
{
|
||||||
CCurve &curve = *It;
|
CCurve &curve = *It;
|
||||||
if(It == m_unite_area->m_curves.begin())
|
if(It == m_unite_area->m_curves.begin())
|
||||||
m_curve = &curve;
|
m_curve = make_shared<CCurve>(curve);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(curve.IsClockwise())curve.Reverse();
|
if(curve.IsClockwise())curve.Reverse();
|
||||||
Insert(&curve);
|
Insert(shared_ptr<CCurve>(new CCurve(curve)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CAreaOrderer::CAreaOrderer()
|
CAreaOrderer::CAreaOrderer()
|
||||||
|
:m_top_level(make_shared<CInnerCurves>())
|
||||||
{
|
{
|
||||||
m_top_level = new CInnerCurves(NULL, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAreaOrderer::Insert(CCurve* pcurve)
|
void CAreaOrderer::Insert(shared_ptr<CCurve> pcurve)
|
||||||
{
|
{
|
||||||
CInnerCurves::area_orderer = this;
|
CInnerCurves::area_orderer = this;
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include <memory>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
|
@ -36,30 +37,31 @@ class CCurve;
|
||||||
|
|
||||||
class CAreaOrderer;
|
class CAreaOrderer;
|
||||||
|
|
||||||
class CInnerCurves
|
class CInnerCurves: public std::enable_shared_from_this<CInnerCurves>
|
||||||
{
|
{
|
||||||
CInnerCurves* m_pOuter;
|
std::shared_ptr<CInnerCurves> m_pOuter;
|
||||||
const CCurve* m_curve; // always empty if top level
|
std::shared_ptr<CCurve> m_curve; // always empty if top level
|
||||||
std::set<CInnerCurves*> m_inner_curves;
|
std::set<std::shared_ptr<CInnerCurves> > m_inner_curves;
|
||||||
CArea *m_unite_area; // new curves made by uniting are stored here
|
std::shared_ptr<CArea> m_unite_area; // new curves made by uniting are stored here
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static CAreaOrderer* area_orderer;
|
static CAreaOrderer* area_orderer;
|
||||||
CInnerCurves(CInnerCurves* pOuter, const CCurve* curve);
|
CInnerCurves(std::shared_ptr<CInnerCurves> pOuter, std::shared_ptr<CCurve> curve);
|
||||||
|
CInnerCurves(){}
|
||||||
~CInnerCurves();
|
~CInnerCurves();
|
||||||
|
|
||||||
void Insert(const CCurve* pcurve);
|
void Insert(std::shared_ptr<CCurve> pcurve);
|
||||||
void GetArea(CArea &area, bool outside = true, bool use_curve = true)const;
|
void GetArea(CArea &area, bool outside = true, bool use_curve = true);
|
||||||
void Unite(const CInnerCurves* c);
|
void Unite(std::shared_ptr<CInnerCurves> c);
|
||||||
};
|
};
|
||||||
|
|
||||||
class CAreaOrderer
|
class CAreaOrderer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CInnerCurves* m_top_level;
|
std::shared_ptr<CInnerCurves> m_top_level;
|
||||||
|
|
||||||
CAreaOrderer();
|
CAreaOrderer();
|
||||||
|
|
||||||
void Insert(CCurve* pcurve);
|
void Insert(std::shared_ptr<CCurve> pcurve);
|
||||||
CArea ResultArea()const;
|
CArea ResultArea()const;
|
||||||
};
|
};
|
Loading…
Reference in New Issue
Block a user