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
|
||||
|
||||
CAreaOrderer ao;
|
||||
std::list<CCurve>::iterator ItLast = m_curves.end();
|
||||
for(std::list<CCurve>::iterator It = m_curves.begin(); It != m_curves.end(); ++It)
|
||||
for(std::list<CCurve>::iterator It = m_curves.begin(), ItNext=It; It != m_curves.end(); It=ItNext)
|
||||
{
|
||||
++ItNext;
|
||||
CCurve& curve = *It;
|
||||
if(!It->IsClosed())
|
||||
continue;
|
||||
ItLast = It;
|
||||
ao.Insert(&curve);
|
||||
ao.Insert(make_shared<CCurve>(curve));
|
||||
if(m_set_processing_length_in_split)
|
||||
{
|
||||
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)
|
||||
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
|
||||
|
|
|
@ -30,29 +30,27 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "AreaOrderer.h"
|
||||
#include "Area.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
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()
|
||||
{
|
||||
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<CInnerCurves*> crossing_these;
|
||||
std::list<shared_ptr<CInnerCurves> > outside_of_these;
|
||||
std::list<shared_ptr<CInnerCurves> > crossing_these;
|
||||
|
||||
// check all inner curves
|
||||
for(std::set<CInnerCurves*>::iterator It = m_inner_curves.begin(); It != m_inner_curves.end(); It++)
|
||||
{
|
||||
CInnerCurves* c = *It;
|
||||
for(shared_ptr<CInnerCurves> c : m_inner_curves) {
|
||||
|
||||
switch(GetOverlapType(*pcurve, *(c->m_curve)))
|
||||
{
|
||||
|
@ -75,28 +73,24 @@ void CInnerCurves::Insert(const CCurve* pcurve)
|
|||
}
|
||||
|
||||
// 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);
|
||||
|
||||
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
|
||||
CInnerCurves* c = *It;
|
||||
c->m_pOuter = new_item;
|
||||
new_item->m_inner_curves.insert(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
|
||||
CInnerCurves* c = *It;
|
||||
new_item->Unite(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)
|
||||
{
|
||||
|
@ -104,11 +98,9 @@ void CInnerCurves::GetArea(CArea &area, bool outside, bool use_curve)const
|
|||
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++)
|
||||
{
|
||||
const CInnerCurves* c = *It;
|
||||
for(shared_ptr<CInnerCurves> c: m_inner_curves) {
|
||||
area.m_curves.push_back(*c->m_curve);
|
||||
if(!outside)area.m_curves.back().Reverse();
|
||||
|
||||
|
@ -116,20 +108,16 @@ void CInnerCurves::GetArea(CArea &area, bool outside, bool use_curve)const
|
|||
else do_after.push_back(c);
|
||||
}
|
||||
|
||||
for(std::list<const CInnerCurves*>::iterator It = do_after.begin(); It != do_after.end(); It++)
|
||||
{
|
||||
const CInnerCurves* c = *It;
|
||||
for(shared_ptr<CInnerCurves> c : do_after)
|
||||
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
|
||||
CArea* new_area = new CArea();
|
||||
shared_ptr<CArea> new_area(new CArea());
|
||||
new_area->m_curves.push_back(*m_curve);
|
||||
delete m_unite_area;
|
||||
m_unite_area = new_area;
|
||||
m_unite_area = new_area;
|
||||
|
||||
CArea a2;
|
||||
c->GetArea(a2);
|
||||
|
@ -140,21 +128,21 @@ void CInnerCurves::Unite(const CInnerCurves* c)
|
|||
{
|
||||
CCurve &curve = *It;
|
||||
if(It == m_unite_area->m_curves.begin())
|
||||
m_curve = &curve;
|
||||
m_curve = make_shared<CCurve>(curve);
|
||||
else
|
||||
{
|
||||
if(curve.IsClockwise())curve.Reverse();
|
||||
Insert(&curve);
|
||||
Insert(shared_ptr<CCurve>(new CCurve(curve)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
|
||||
#pragma once
|
||||
#include <memory>
|
||||
#include <list>
|
||||
#include <set>
|
||||
|
||||
|
@ -36,30 +37,31 @@ class CCurve;
|
|||
|
||||
class CAreaOrderer;
|
||||
|
||||
class CInnerCurves
|
||||
class CInnerCurves: public std::enable_shared_from_this<CInnerCurves>
|
||||
{
|
||||
CInnerCurves* m_pOuter;
|
||||
const CCurve* m_curve; // always empty if top level
|
||||
std::set<CInnerCurves*> m_inner_curves;
|
||||
CArea *m_unite_area; // new curves made by uniting are stored here
|
||||
std::shared_ptr<CInnerCurves> m_pOuter;
|
||||
std::shared_ptr<CCurve> m_curve; // always empty if top level
|
||||
std::set<std::shared_ptr<CInnerCurves> > m_inner_curves;
|
||||
std::shared_ptr<CArea> m_unite_area; // new curves made by uniting are stored here
|
||||
|
||||
public:
|
||||
static CAreaOrderer* area_orderer;
|
||||
CInnerCurves(CInnerCurves* pOuter, const CCurve* curve);
|
||||
CInnerCurves(std::shared_ptr<CInnerCurves> pOuter, std::shared_ptr<CCurve> curve);
|
||||
CInnerCurves(){}
|
||||
~CInnerCurves();
|
||||
|
||||
void Insert(const CCurve* pcurve);
|
||||
void GetArea(CArea &area, bool outside = true, bool use_curve = true)const;
|
||||
void Unite(const CInnerCurves* c);
|
||||
void Insert(std::shared_ptr<CCurve> pcurve);
|
||||
void GetArea(CArea &area, bool outside = true, bool use_curve = true);
|
||||
void Unite(std::shared_ptr<CInnerCurves> c);
|
||||
};
|
||||
|
||||
class CAreaOrderer
|
||||
{
|
||||
public:
|
||||
CInnerCurves* m_top_level;
|
||||
std::shared_ptr<CInnerCurves> m_top_level;
|
||||
|
||||
CAreaOrderer();
|
||||
|
||||
void Insert(CCurve* pcurve);
|
||||
void Insert(std::shared_ptr<CCurve> pcurve);
|
||||
CArea ResultArea()const;
|
||||
};
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue
Block a user