initial add of libarea files
This commit is contained in:
committed by
Yorik van Havre
parent
f52401715d
commit
797a6f1ddb
153
src/Mod/Path/libarea/AreaOrderer.cpp
Normal file
153
src/Mod/Path/libarea/AreaOrderer.cpp
Normal file
@@ -0,0 +1,153 @@
|
||||
// AreaOrderer.cpp
|
||||
// Copyright (c) 2010, Dan Heeks
|
||||
// This program is released under the BSD license. See the file COPYING for details.
|
||||
|
||||
#include "AreaOrderer.h"
|
||||
#include "Area.h"
|
||||
|
||||
CAreaOrderer* CInnerCurves::area_orderer = NULL;
|
||||
|
||||
CInnerCurves::CInnerCurves(CInnerCurves* pOuter, const CCurve* curve)
|
||||
{
|
||||
m_pOuter = pOuter;
|
||||
m_curve = curve;
|
||||
m_unite_area = NULL;
|
||||
}
|
||||
|
||||
CInnerCurves::~CInnerCurves()
|
||||
{
|
||||
delete m_unite_area;
|
||||
}
|
||||
|
||||
void CInnerCurves::Insert(const CCurve* pcurve)
|
||||
{
|
||||
std::list<CInnerCurves*> outside_of_these;
|
||||
std::list<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;
|
||||
|
||||
switch(GetOverlapType(*pcurve, *(c->m_curve)))
|
||||
{
|
||||
case eOutside:
|
||||
outside_of_these.push_back(c);
|
||||
break;
|
||||
|
||||
case eInside:
|
||||
// insert in this inner curve
|
||||
c->Insert(pcurve);
|
||||
return;
|
||||
|
||||
case eSiblings:
|
||||
break;
|
||||
|
||||
case eCrossing:
|
||||
crossing_these.push_back(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// add as a new inner
|
||||
CInnerCurves* new_item = new CInnerCurves(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++)
|
||||
{
|
||||
// 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++)
|
||||
{
|
||||
// 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
|
||||
{
|
||||
if(use_curve && m_curve)
|
||||
{
|
||||
area.m_curves.push_back(*m_curve);
|
||||
outside = !outside;
|
||||
}
|
||||
|
||||
std::list<const CInnerCurves*> do_after;
|
||||
|
||||
for(std::set<CInnerCurves*>::const_iterator It = m_inner_curves.begin(); It != m_inner_curves.end(); It++)
|
||||
{
|
||||
const CInnerCurves* c = *It;
|
||||
area.m_curves.push_back(*c->m_curve);
|
||||
if(!outside)area.m_curves.back().Reverse();
|
||||
|
||||
if(outside)c->GetArea(area, !outside, false);
|
||||
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;
|
||||
c->GetArea(area, !outside, false);
|
||||
}
|
||||
}
|
||||
|
||||
void CInnerCurves::Unite(const CInnerCurves* c)
|
||||
{
|
||||
// unite all the curves in c, with this one
|
||||
CArea* new_area = new CArea();
|
||||
new_area->m_curves.push_back(*m_curve);
|
||||
delete m_unite_area;
|
||||
m_unite_area = new_area;
|
||||
|
||||
CArea a2;
|
||||
c->GetArea(a2);
|
||||
|
||||
m_unite_area->Union(a2);
|
||||
m_unite_area->Reorder();
|
||||
for(std::list<CCurve>::iterator It = m_unite_area->m_curves.begin(); It != m_unite_area->m_curves.end(); It++)
|
||||
{
|
||||
CCurve &curve = *It;
|
||||
if(It == m_unite_area->m_curves.begin())
|
||||
m_curve = &curve;
|
||||
else
|
||||
{
|
||||
if(curve.IsClockwise())curve.Reverse();
|
||||
Insert(&curve);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CAreaOrderer::CAreaOrderer()
|
||||
{
|
||||
m_top_level = new CInnerCurves(NULL, NULL);
|
||||
}
|
||||
|
||||
void CAreaOrderer::Insert(CCurve* pcurve)
|
||||
{
|
||||
CInnerCurves::area_orderer = this;
|
||||
|
||||
// make them all anti-clockwise as they come in
|
||||
if(pcurve->IsClockwise())pcurve->Reverse();
|
||||
|
||||
m_top_level->Insert(pcurve);
|
||||
}
|
||||
|
||||
CArea CAreaOrderer::ResultArea()const
|
||||
{
|
||||
CArea a;
|
||||
|
||||
if(m_top_level)
|
||||
{
|
||||
m_top_level->GetArea(a);
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user