mirror of https://github.com/KLayout/klayout.git
WIP: copy-on-write for FlatRegion and FlatEdges too
This commit is contained in:
parent
cc58d7d8ee
commit
cdcac6f5d3
|
|
@ -33,7 +33,7 @@ namespace db
|
|||
// FlatEdges implementation
|
||||
|
||||
FlatEdges::FlatEdges ()
|
||||
: AsIfFlatEdges (), m_edges (false), m_merged_edges (false)
|
||||
: AsIfFlatEdges (), mp_edges (new db::Shapes (false)), mp_merged_edges (new db::Shapes (false))
|
||||
{
|
||||
init ();
|
||||
}
|
||||
|
|
@ -44,18 +44,16 @@ FlatEdges::~FlatEdges ()
|
|||
}
|
||||
|
||||
FlatEdges::FlatEdges (const FlatEdges &other)
|
||||
: AsIfFlatEdges (other), m_edges (false), m_merged_edges (false)
|
||||
: AsIfFlatEdges (other), mp_edges (other.mp_edges), mp_merged_edges (other.mp_merged_edges)
|
||||
{
|
||||
init ();
|
||||
|
||||
m_is_merged = other.m_is_merged;
|
||||
m_edges = other.m_edges;
|
||||
m_merged_edges = other.m_merged_edges;
|
||||
m_merged_edges_valid = other.m_merged_edges_valid;
|
||||
}
|
||||
|
||||
FlatEdges::FlatEdges (const db::Shapes &edges, bool is_merged)
|
||||
: AsIfFlatEdges (), m_edges (edges), m_merged_edges (false)
|
||||
: AsIfFlatEdges (), mp_edges (new db::Shapes (edges)), mp_merged_edges (new db::Shapes (false))
|
||||
{
|
||||
init ();
|
||||
|
||||
|
|
@ -63,7 +61,7 @@ FlatEdges::FlatEdges (const db::Shapes &edges, bool is_merged)
|
|||
}
|
||||
|
||||
FlatEdges::FlatEdges (bool is_merged)
|
||||
: AsIfFlatEdges (), m_edges (false), m_merged_edges (false)
|
||||
: AsIfFlatEdges (), mp_edges (new db::Shapes (false)), mp_merged_edges (new db::Shapes (false))
|
||||
{
|
||||
init ();
|
||||
|
||||
|
|
@ -78,7 +76,7 @@ void FlatEdges::set_is_merged (bool m)
|
|||
void FlatEdges::invalidate_cache ()
|
||||
{
|
||||
invalidate_bbox ();
|
||||
m_merged_edges.clear ();
|
||||
mp_merged_edges->clear ();
|
||||
m_merged_edges_valid = false;
|
||||
}
|
||||
|
||||
|
|
@ -90,18 +88,18 @@ void FlatEdges::init ()
|
|||
|
||||
void FlatEdges::insert_into (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer) const
|
||||
{
|
||||
layout->cell (into_cell).shapes (into_layer).insert (m_edges);
|
||||
layout->cell (into_cell).shapes (into_layer).insert (*mp_edges);
|
||||
}
|
||||
|
||||
void FlatEdges::merged_semantics_changed ()
|
||||
{
|
||||
m_merged_edges.clear ();
|
||||
mp_merged_edges->clear ();
|
||||
m_merged_edges_valid = false;
|
||||
}
|
||||
|
||||
void FlatEdges::reserve (size_t n)
|
||||
{
|
||||
m_edges.reserve (db::Edge::tag (), n);
|
||||
mp_edges->reserve (db::Edge::tag (), n);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -109,13 +107,13 @@ FlatEdges::ensure_merged_edges_valid () const
|
|||
{
|
||||
if (! m_merged_edges_valid) {
|
||||
|
||||
m_merged_edges.clear ();
|
||||
mp_merged_edges->clear ();
|
||||
|
||||
db::Shapes tmp (false);
|
||||
EdgeBooleanClusterCollectorToShapes cluster_collector (&tmp, EdgeOr);
|
||||
|
||||
db::box_scanner<db::Edge, size_t> scanner (report_progress (), progress_desc ());
|
||||
scanner.reserve (m_edges.size ());
|
||||
scanner.reserve (mp_edges->size ());
|
||||
|
||||
for (EdgesIterator e (begin ()); ! e.at_end (); ++e) {
|
||||
if (! e->is_degenerate ()) {
|
||||
|
|
@ -125,7 +123,7 @@ FlatEdges::ensure_merged_edges_valid () const
|
|||
|
||||
scanner.process (cluster_collector, 1, db::box_convert<db::Edge> ());
|
||||
|
||||
m_merged_edges.swap (tmp);
|
||||
mp_merged_edges->swap (tmp);
|
||||
m_merged_edges_valid = true;
|
||||
|
||||
}
|
||||
|
|
@ -133,7 +131,7 @@ FlatEdges::ensure_merged_edges_valid () const
|
|||
|
||||
EdgesIteratorDelegate *FlatEdges::begin () const
|
||||
{
|
||||
return new FlatEdgesIterator (&m_edges);
|
||||
return new FlatEdgesIterator (mp_edges.get_const ());
|
||||
}
|
||||
|
||||
EdgesIteratorDelegate *FlatEdges::begin_merged () const
|
||||
|
|
@ -142,13 +140,13 @@ EdgesIteratorDelegate *FlatEdges::begin_merged () const
|
|||
return begin ();
|
||||
} else {
|
||||
ensure_merged_edges_valid ();
|
||||
return new FlatEdgesIterator (&m_merged_edges);
|
||||
return new FlatEdgesIterator (mp_merged_edges.get_const ());
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<db::RecursiveShapeIterator, db::ICplxTrans> FlatEdges::begin_iter () const
|
||||
{
|
||||
return std::make_pair (db::RecursiveShapeIterator (m_edges), db::ICplxTrans ());
|
||||
return std::make_pair (db::RecursiveShapeIterator (*mp_edges), db::ICplxTrans ());
|
||||
}
|
||||
|
||||
std::pair<db::RecursiveShapeIterator, db::ICplxTrans> FlatEdges::begin_merged_iter () const
|
||||
|
|
@ -157,23 +155,23 @@ std::pair<db::RecursiveShapeIterator, db::ICplxTrans> FlatEdges::begin_merged_it
|
|||
return begin_iter ();
|
||||
} else {
|
||||
ensure_merged_edges_valid ();
|
||||
return std::make_pair (db::RecursiveShapeIterator (m_merged_edges), db::ICplxTrans ());
|
||||
return std::make_pair (db::RecursiveShapeIterator (*mp_merged_edges), db::ICplxTrans ());
|
||||
}
|
||||
}
|
||||
|
||||
bool FlatEdges::empty () const
|
||||
{
|
||||
return m_edges.empty ();
|
||||
return mp_edges->empty ();
|
||||
}
|
||||
|
||||
size_t FlatEdges::count () const
|
||||
{
|
||||
return m_edges.size ();
|
||||
return mp_edges->size ();
|
||||
}
|
||||
|
||||
size_t FlatEdges::hier_count () const
|
||||
{
|
||||
return m_edges.size ();
|
||||
return mp_edges->size ();
|
||||
}
|
||||
|
||||
bool FlatEdges::is_merged () const
|
||||
|
|
@ -183,8 +181,8 @@ bool FlatEdges::is_merged () const
|
|||
|
||||
Box FlatEdges::compute_bbox () const
|
||||
{
|
||||
m_edges.update_bbox ();
|
||||
return m_edges.bbox ();
|
||||
mp_edges->update_bbox ();
|
||||
return mp_edges->bbox ();
|
||||
}
|
||||
|
||||
EdgesDelegate *
|
||||
|
|
@ -192,25 +190,27 @@ FlatEdges::processed_in_place (const EdgeProcessorBase &filter)
|
|||
{
|
||||
std::vector<db::Edge> edge_res;
|
||||
|
||||
edge_iterator_type pw = m_edges.get_layer<db::Edge, db::unstable_layer_tag> ().begin ();
|
||||
db::Shapes &e = *mp_edges;
|
||||
|
||||
edge_iterator_type pw = e.get_layer<db::Edge, db::unstable_layer_tag> ().begin ();
|
||||
for (EdgesIterator p (filter.requires_raw_input () ? begin () : begin_merged ()); ! p.at_end (); ++p) {
|
||||
|
||||
edge_res.clear ();
|
||||
filter.process (*p, edge_res);
|
||||
|
||||
for (std::vector<db::Edge>::const_iterator pr = edge_res.begin (); pr != edge_res.end (); ++pr) {
|
||||
if (pw == m_edges.get_layer<db::Edge, db::unstable_layer_tag> ().end ()) {
|
||||
m_edges.get_layer<db::Edge, db::unstable_layer_tag> ().insert (*pr);
|
||||
pw = m_edges.get_layer<db::Edge, db::unstable_layer_tag> ().end ();
|
||||
if (pw == e.get_layer<db::Edge, db::unstable_layer_tag> ().end ()) {
|
||||
e.get_layer<db::Edge, db::unstable_layer_tag> ().insert (*pr);
|
||||
pw = e.get_layer<db::Edge, db::unstable_layer_tag> ().end ();
|
||||
} else {
|
||||
m_edges.get_layer<db::Edge, db::unstable_layer_tag> ().replace (pw++, *pr);
|
||||
e.get_layer<db::Edge, db::unstable_layer_tag> ().replace (pw++, *pr);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
m_edges.get_layer<db::Edge, db::unstable_layer_tag> ().erase (pw, m_edges.get_layer<db::Edge, db::unstable_layer_tag> ().end ());
|
||||
m_merged_edges.clear ();
|
||||
e.get_layer<db::Edge, db::unstable_layer_tag> ().erase (pw, e.get_layer<db::Edge, db::unstable_layer_tag> ().end ());
|
||||
mp_merged_edges->clear ();
|
||||
m_is_merged = filter.result_is_merged () && merged_semantics ();
|
||||
|
||||
return this;
|
||||
|
|
@ -219,20 +219,22 @@ FlatEdges::processed_in_place (const EdgeProcessorBase &filter)
|
|||
EdgesDelegate *
|
||||
FlatEdges::filter_in_place (const EdgeFilterBase &filter)
|
||||
{
|
||||
edge_iterator_type pw = m_edges.get_layer<db::Edge, db::unstable_layer_tag> ().begin ();
|
||||
db::Shapes &e = *mp_edges;
|
||||
|
||||
edge_iterator_type pw = e.get_layer<db::Edge, db::unstable_layer_tag> ().begin ();
|
||||
for (EdgesIterator p (begin_merged ()); ! p.at_end (); ++p) {
|
||||
if (filter.selected (*p)) {
|
||||
if (pw == m_edges.get_layer<db::Edge, db::unstable_layer_tag> ().end ()) {
|
||||
m_edges.get_layer<db::Edge, db::unstable_layer_tag> ().insert (*p);
|
||||
pw = m_edges.get_layer<db::Edge, db::unstable_layer_tag> ().end ();
|
||||
if (pw == e.get_layer<db::Edge, db::unstable_layer_tag> ().end ()) {
|
||||
e.get_layer<db::Edge, db::unstable_layer_tag> ().insert (*p);
|
||||
pw = e.get_layer<db::Edge, db::unstable_layer_tag> ().end ();
|
||||
} else {
|
||||
m_edges.get_layer<db::Edge, db::unstable_layer_tag> ().replace (pw++, *p);
|
||||
e.get_layer<db::Edge, db::unstable_layer_tag> ().replace (pw++, *p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_edges.get_layer<db::Edge, db::unstable_layer_tag> ().erase (pw, m_edges.get_layer<db::Edge, db::unstable_layer_tag> ().end ());
|
||||
m_merged_edges.clear ();
|
||||
e.get_layer<db::Edge, db::unstable_layer_tag> ().erase (pw, e.get_layer<db::Edge, db::unstable_layer_tag> ().end ());
|
||||
mp_merged_edges->clear ();
|
||||
m_is_merged = merged_semantics ();
|
||||
|
||||
return this;
|
||||
|
|
@ -272,22 +274,24 @@ EdgesDelegate *FlatEdges::add_in_place (const Edges &other)
|
|||
invalidate_cache ();
|
||||
m_is_merged = false;
|
||||
|
||||
db::Shapes &e = *mp_edges;
|
||||
|
||||
FlatEdges *other_flat = dynamic_cast<FlatEdges *> (other.delegate ());
|
||||
if (other_flat) {
|
||||
|
||||
m_edges.insert (other_flat->raw_edges ().get_layer<db::Edge, db::unstable_layer_tag> ().begin (), other_flat->raw_edges ().get_layer<db::Edge, db::unstable_layer_tag> ().end ());
|
||||
e.insert (other_flat->raw_edges ().get_layer<db::Edge, db::unstable_layer_tag> ().begin (), other_flat->raw_edges ().get_layer<db::Edge, db::unstable_layer_tag> ().end ());
|
||||
|
||||
} else {
|
||||
|
||||
size_t n = m_edges.size ();
|
||||
size_t n = e.size ();
|
||||
for (EdgesIterator p (other.begin ()); ! p.at_end (); ++p) {
|
||||
++n;
|
||||
}
|
||||
|
||||
m_edges.reserve (db::Edge::tag (), n);
|
||||
e.reserve (db::Edge::tag (), n);
|
||||
|
||||
for (EdgesIterator p (other.begin ()); ! p.at_end (); ++p) {
|
||||
m_edges.insert (*p);
|
||||
e.insert (*p);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -297,7 +301,7 @@ EdgesDelegate *FlatEdges::add_in_place (const Edges &other)
|
|||
|
||||
const db::Edge *FlatEdges::nth (size_t n) const
|
||||
{
|
||||
return n < m_edges.size () ? &m_edges.get_layer<db::Edge, db::unstable_layer_tag> ().begin () [n] : 0;
|
||||
return n < mp_edges->size () ? &mp_edges->get_layer<db::Edge, db::unstable_layer_tag> ().begin () [n] : 0;
|
||||
}
|
||||
|
||||
bool FlatEdges::has_valid_edges () const
|
||||
|
|
@ -322,10 +326,11 @@ FlatEdges::insert (const db::Box &box)
|
|||
|
||||
bool was_empty = empty ();
|
||||
|
||||
m_edges.insert (db::Edge (box.lower_left (), box.upper_left ()));
|
||||
m_edges.insert (db::Edge (box.upper_left (), box.upper_right ()));
|
||||
m_edges.insert (db::Edge (box.upper_right (), box.lower_right ()));
|
||||
m_edges.insert (db::Edge (box.lower_right (), box.lower_left ()));
|
||||
db::Shapes &e = *mp_edges;
|
||||
e.insert (db::Edge (box.lower_left (), box.upper_left ()));
|
||||
e.insert (db::Edge (box.upper_left (), box.upper_right ()));
|
||||
e.insert (db::Edge (box.upper_right (), box.lower_right ()));
|
||||
e.insert (db::Edge (box.lower_right (), box.lower_left ()));
|
||||
|
||||
if (was_empty) {
|
||||
|
||||
|
|
@ -354,8 +359,9 @@ void
|
|||
FlatEdges::insert (const db::Polygon &polygon)
|
||||
{
|
||||
if (polygon.holes () > 0 || polygon.vertices () > 0) {
|
||||
db::Shapes &edges = *mp_edges;
|
||||
for (db::Polygon::polygon_edge_iterator e = polygon.begin_edge (); ! e.at_end (); ++e) {
|
||||
m_edges.insert (*e);
|
||||
edges.insert (*e);
|
||||
}
|
||||
m_is_merged = false;
|
||||
invalidate_cache ();
|
||||
|
|
@ -366,8 +372,9 @@ void
|
|||
FlatEdges::insert (const db::SimplePolygon &polygon)
|
||||
{
|
||||
if (polygon.vertices () > 0) {
|
||||
db::Shapes &edges = *mp_edges;
|
||||
for (db::SimplePolygon::polygon_edge_iterator e = polygon.begin_edge (); ! e.at_end (); ++e) {
|
||||
m_edges.insert (*e);
|
||||
edges.insert (*e);
|
||||
}
|
||||
m_is_merged = false;
|
||||
invalidate_cache ();
|
||||
|
|
@ -381,7 +388,7 @@ FlatEdges::insert (const db::Edge &edge)
|
|||
m_is_merged = false;
|
||||
}
|
||||
|
||||
m_edges.insert (edge);
|
||||
mp_edges->insert (edge);
|
||||
invalidate_cache ();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include "dbShapes.h"
|
||||
#include "dbShapes2.h"
|
||||
#include "dbGenericShapeIterator.h"
|
||||
#include "tlCopyOnWrite.h"
|
||||
|
||||
namespace db {
|
||||
|
||||
|
|
@ -138,14 +139,16 @@ public:
|
|||
void transform (const Trans &trans)
|
||||
{
|
||||
if (! trans.is_unity ()) {
|
||||
for (edge_iterator_type p = m_edges.template get_layer<db::Edge, db::unstable_layer_tag> ().begin (); p != m_edges.get_layer<db::Edge, db::unstable_layer_tag> ().end (); ++p) {
|
||||
m_edges.get_layer<db::Edge, db::unstable_layer_tag> ().replace (p, p->transformed (trans));
|
||||
db::Shapes &e = *mp_edges;
|
||||
for (edge_iterator_type p = e.template get_layer<db::Edge, db::unstable_layer_tag> ().begin (); p != e.get_layer<db::Edge, db::unstable_layer_tag> ().end (); ++p) {
|
||||
e.get_layer<db::Edge, db::unstable_layer_tag> ().replace (p, p->transformed (trans));
|
||||
}
|
||||
invalidate_cache ();
|
||||
}
|
||||
}
|
||||
|
||||
db::Shapes &raw_edges () { return m_edges; }
|
||||
db::Shapes &raw_edges () { return *mp_edges; }
|
||||
const db::Shapes &raw_edges () const { return *mp_edges; }
|
||||
|
||||
protected:
|
||||
virtual void merged_semantics_changed ();
|
||||
|
|
@ -159,8 +162,8 @@ private:
|
|||
FlatEdges &operator= (const FlatEdges &other);
|
||||
|
||||
bool m_is_merged;
|
||||
mutable db::Shapes m_edges;
|
||||
mutable db::Shapes m_merged_edges;
|
||||
mutable tl::copy_on_write_ptr<db::Shapes> mp_edges;
|
||||
mutable tl::copy_on_write_ptr<db::Shapes> mp_merged_edges;
|
||||
mutable bool m_merged_edges_valid;
|
||||
|
||||
void init ();
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ namespace db
|
|||
// FlatRegion implementation
|
||||
|
||||
FlatRegion::FlatRegion ()
|
||||
: AsIfFlatRegion (), m_polygons (false), m_merged_polygons (false)
|
||||
: AsIfFlatRegion (), mp_polygons (new db::Shapes (false)), mp_merged_polygons (new db::Shapes (false))
|
||||
{
|
||||
init ();
|
||||
}
|
||||
|
|
@ -44,18 +44,16 @@ FlatRegion::~FlatRegion ()
|
|||
}
|
||||
|
||||
FlatRegion::FlatRegion (const FlatRegion &other)
|
||||
: AsIfFlatRegion (other), m_polygons (false), m_merged_polygons (false)
|
||||
: AsIfFlatRegion (other), mp_polygons (other.mp_polygons), mp_merged_polygons (other.mp_merged_polygons)
|
||||
{
|
||||
init ();
|
||||
|
||||
m_is_merged = other.m_is_merged;
|
||||
m_polygons = other.m_polygons;
|
||||
m_merged_polygons = other.m_merged_polygons;
|
||||
m_merged_polygons_valid = other.m_merged_polygons_valid;
|
||||
}
|
||||
|
||||
FlatRegion::FlatRegion (const db::Shapes &polygons, bool is_merged)
|
||||
: AsIfFlatRegion (), m_polygons (polygons), m_merged_polygons (false)
|
||||
: AsIfFlatRegion (), mp_polygons (new db::Shapes (polygons)), mp_merged_polygons (new db::Shapes (false))
|
||||
{
|
||||
init ();
|
||||
|
||||
|
|
@ -63,7 +61,7 @@ FlatRegion::FlatRegion (const db::Shapes &polygons, bool is_merged)
|
|||
}
|
||||
|
||||
FlatRegion::FlatRegion (bool is_merged)
|
||||
: AsIfFlatRegion (), m_polygons (false), m_merged_polygons (false)
|
||||
: AsIfFlatRegion (), mp_polygons (new db::Shapes (false)), mp_merged_polygons (new db::Shapes (false))
|
||||
{
|
||||
init ();
|
||||
|
||||
|
|
@ -78,7 +76,7 @@ void FlatRegion::set_is_merged (bool m)
|
|||
void FlatRegion::invalidate_cache ()
|
||||
{
|
||||
invalidate_bbox ();
|
||||
m_merged_polygons.clear ();
|
||||
mp_merged_polygons->clear ();
|
||||
m_merged_polygons_valid = false;
|
||||
}
|
||||
|
||||
|
|
@ -90,20 +88,20 @@ void FlatRegion::init ()
|
|||
|
||||
void FlatRegion::merged_semantics_changed ()
|
||||
{
|
||||
m_merged_polygons.clear ();
|
||||
mp_merged_polygons->clear ();
|
||||
m_merged_polygons_valid = false;
|
||||
}
|
||||
|
||||
void FlatRegion::min_coherence_changed ()
|
||||
{
|
||||
m_is_merged = false;
|
||||
m_merged_polygons.clear ();
|
||||
mp_merged_polygons->clear ();
|
||||
m_merged_polygons_valid = false;
|
||||
}
|
||||
|
||||
void FlatRegion::reserve (size_t n)
|
||||
{
|
||||
m_polygons.reserve (db::Polygon::tag (), n);
|
||||
mp_polygons->reserve (db::Polygon::tag (), n);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -111,7 +109,7 @@ FlatRegion::ensure_merged_polygons_valid () const
|
|||
{
|
||||
if (! m_merged_polygons_valid) {
|
||||
|
||||
m_merged_polygons.clear ();
|
||||
mp_merged_polygons->clear ();
|
||||
|
||||
db::EdgeProcessor ep (report_progress (), progress_desc ());
|
||||
ep.set_base_verbosity (base_verbosity ());
|
||||
|
|
@ -131,7 +129,7 @@ FlatRegion::ensure_merged_polygons_valid () const
|
|||
|
||||
// and run the merge step
|
||||
db::MergeOp op (0);
|
||||
db::ShapeGenerator pc (m_merged_polygons);
|
||||
db::ShapeGenerator pc (*mp_merged_polygons);
|
||||
db::PolygonGenerator pg (pc, false /*don't resolve holes*/, min_coherence ());
|
||||
ep.process (pg, op);
|
||||
|
||||
|
|
@ -142,7 +140,7 @@ FlatRegion::ensure_merged_polygons_valid () const
|
|||
|
||||
RegionIteratorDelegate *FlatRegion::begin () const
|
||||
{
|
||||
return new FlatRegionIterator (&m_polygons);
|
||||
return new FlatRegionIterator (mp_polygons.get_const ());
|
||||
}
|
||||
|
||||
RegionIteratorDelegate *FlatRegion::begin_merged () const
|
||||
|
|
@ -151,13 +149,13 @@ RegionIteratorDelegate *FlatRegion::begin_merged () const
|
|||
return begin ();
|
||||
} else {
|
||||
ensure_merged_polygons_valid ();
|
||||
return new FlatRegionIterator (&m_merged_polygons);
|
||||
return new FlatRegionIterator (mp_merged_polygons.get_const ());
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<db::RecursiveShapeIterator, db::ICplxTrans> FlatRegion::begin_iter () const
|
||||
{
|
||||
return std::make_pair (db::RecursiveShapeIterator (m_polygons), db::ICplxTrans ());
|
||||
return std::make_pair (db::RecursiveShapeIterator (*mp_polygons), db::ICplxTrans ());
|
||||
}
|
||||
|
||||
std::pair<db::RecursiveShapeIterator, db::ICplxTrans> FlatRegion::begin_merged_iter () const
|
||||
|
|
@ -166,23 +164,23 @@ std::pair<db::RecursiveShapeIterator, db::ICplxTrans> FlatRegion::begin_merged_i
|
|||
return begin_iter ();
|
||||
} else {
|
||||
ensure_merged_polygons_valid ();
|
||||
return std::make_pair (db::RecursiveShapeIterator (m_merged_polygons), db::ICplxTrans ());
|
||||
return std::make_pair (db::RecursiveShapeIterator (*mp_merged_polygons), db::ICplxTrans ());
|
||||
}
|
||||
}
|
||||
|
||||
bool FlatRegion::empty () const
|
||||
{
|
||||
return m_polygons.empty ();
|
||||
return mp_polygons->empty ();
|
||||
}
|
||||
|
||||
size_t FlatRegion::count () const
|
||||
{
|
||||
return m_polygons.size ();
|
||||
return mp_polygons->size ();
|
||||
}
|
||||
|
||||
size_t FlatRegion::hier_count () const
|
||||
{
|
||||
return m_polygons.size ();
|
||||
return mp_polygons->size ();
|
||||
}
|
||||
|
||||
bool FlatRegion::is_merged () const
|
||||
|
|
@ -192,13 +190,13 @@ bool FlatRegion::is_merged () const
|
|||
|
||||
Box FlatRegion::compute_bbox () const
|
||||
{
|
||||
m_polygons.update_bbox ();
|
||||
return m_polygons.bbox ();
|
||||
mp_polygons->update_bbox ();
|
||||
return mp_polygons->bbox ();
|
||||
}
|
||||
|
||||
RegionDelegate *FlatRegion::filter_in_place (const PolygonFilterBase &filter)
|
||||
{
|
||||
db::layer<db::Polygon, db::unstable_layer_tag> &poly_layer = m_polygons.get_layer<db::Polygon, db::unstable_layer_tag> ();
|
||||
db::layer<db::Polygon, db::unstable_layer_tag> &poly_layer = mp_polygons->get_layer<db::Polygon, db::unstable_layer_tag> ();
|
||||
|
||||
polygon_iterator_type pw = poly_layer.begin ();
|
||||
for (RegionIterator p (filter.requires_raw_input () ? begin () : begin_merged ()); ! p.at_end (); ++p) {
|
||||
|
|
@ -214,7 +212,7 @@ RegionDelegate *FlatRegion::filter_in_place (const PolygonFilterBase &filter)
|
|||
|
||||
poly_layer.erase (pw, poly_layer.end ());
|
||||
|
||||
m_merged_polygons.clear ();
|
||||
mp_merged_polygons->clear ();
|
||||
m_is_merged = filter.requires_raw_input () ? false : merged_semantics ();
|
||||
|
||||
return this;
|
||||
|
|
@ -222,7 +220,7 @@ RegionDelegate *FlatRegion::filter_in_place (const PolygonFilterBase &filter)
|
|||
|
||||
RegionDelegate *FlatRegion::process_in_place (const PolygonProcessorBase &filter)
|
||||
{
|
||||
db::layer<db::Polygon, db::unstable_layer_tag> &poly_layer = m_polygons.get_layer<db::Polygon, db::unstable_layer_tag> ();
|
||||
db::layer<db::Polygon, db::unstable_layer_tag> &poly_layer = mp_polygons->get_layer<db::Polygon, db::unstable_layer_tag> ();
|
||||
db::layer<db::Polygon, db::unstable_layer_tag> out;
|
||||
|
||||
std::vector<db::Polygon> poly_res;
|
||||
|
|
@ -234,7 +232,7 @@ RegionDelegate *FlatRegion::process_in_place (const PolygonProcessorBase &filter
|
|||
|
||||
poly_layer.swap (out);
|
||||
|
||||
m_merged_polygons.clear ();
|
||||
mp_merged_polygons->clear ();
|
||||
m_is_merged = filter.result_is_merged () && merged_semantics ();
|
||||
|
||||
if (filter.result_must_not_be_merged ()) {
|
||||
|
|
@ -250,8 +248,9 @@ RegionDelegate *FlatRegion::merged_in_place ()
|
|||
|
||||
if (m_merged_polygons_valid) {
|
||||
|
||||
m_polygons.swap (m_merged_polygons);
|
||||
m_merged_polygons.clear ();
|
||||
db::Shapes &merged_polygons = *mp_merged_polygons;
|
||||
mp_polygons->swap (merged_polygons);
|
||||
merged_polygons.clear ();
|
||||
m_is_merged = true;
|
||||
return this;
|
||||
|
||||
|
|
@ -300,7 +299,7 @@ RegionDelegate *FlatRegion::merged_in_place (bool min_coherence, unsigned int mi
|
|||
|
||||
// and run the merge step
|
||||
db::MergeOp op (min_wc);
|
||||
db::ShapeGenerator pc (m_polygons, true /*clear*/);
|
||||
db::ShapeGenerator pc (*mp_polygons, true /*clear*/);
|
||||
db::PolygonGenerator pg (pc, false /*don't resolve holes*/, min_coherence);
|
||||
ep.process (pg, op);
|
||||
|
||||
|
|
@ -316,7 +315,7 @@ RegionDelegate *FlatRegion::merged () const
|
|||
if (! m_is_merged) {
|
||||
|
||||
if (m_merged_polygons_valid) {
|
||||
return new FlatRegion (m_merged_polygons, true);
|
||||
return new FlatRegion (*mp_merged_polygons, true);
|
||||
} else {
|
||||
return AsIfFlatRegion::merged (min_coherence (), 0);
|
||||
}
|
||||
|
|
@ -360,22 +359,24 @@ RegionDelegate *FlatRegion::add_in_place (const Region &other)
|
|||
invalidate_cache ();
|
||||
m_is_merged = false;
|
||||
|
||||
db::Shapes &polygons = *mp_polygons;
|
||||
|
||||
FlatRegion *other_flat = dynamic_cast<FlatRegion *> (other.delegate ());
|
||||
if (other_flat) {
|
||||
|
||||
m_polygons.insert (other_flat->raw_polygons ().get_layer<db::Polygon, db::unstable_layer_tag> ().begin (), other_flat->raw_polygons ().get_layer<db::Polygon, db::unstable_layer_tag> ().end ());
|
||||
polygons.insert (other_flat->raw_polygons ().get_layer<db::Polygon, db::unstable_layer_tag> ().begin (), other_flat->raw_polygons ().get_layer<db::Polygon, db::unstable_layer_tag> ().end ());
|
||||
|
||||
} else {
|
||||
|
||||
size_t n = m_polygons.size ();
|
||||
size_t n = polygons.size ();
|
||||
for (RegionIterator p (other.begin ()); ! p.at_end (); ++p) {
|
||||
++n;
|
||||
}
|
||||
|
||||
m_polygons.reserve (db::Polygon::tag (), n);
|
||||
polygons.reserve (db::Polygon::tag (), n);
|
||||
|
||||
for (RegionIterator p (other.begin ()); ! p.at_end (); ++p) {
|
||||
m_polygons.insert (*p);
|
||||
polygons.insert (*p);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -385,7 +386,7 @@ RegionDelegate *FlatRegion::add_in_place (const Region &other)
|
|||
|
||||
const db::Polygon *FlatRegion::nth (size_t n) const
|
||||
{
|
||||
return n < m_polygons.size () ? &m_polygons.get_layer<db::Polygon, db::unstable_layer_tag> ().begin () [n] : 0;
|
||||
return n < mp_polygons->size () ? &mp_polygons->get_layer<db::Polygon, db::unstable_layer_tag> ().begin () [n] : 0;
|
||||
}
|
||||
|
||||
bool FlatRegion::has_valid_polygons () const
|
||||
|
|
@ -405,7 +406,7 @@ const db::RecursiveShapeIterator *FlatRegion::iter () const
|
|||
|
||||
void FlatRegion::insert_into (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer) const
|
||||
{
|
||||
layout->cell (into_cell).shapes (into_layer).insert (m_polygons);
|
||||
layout->cell (into_cell).shapes (into_layer).insert (*mp_polygons);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -415,13 +416,13 @@ FlatRegion::insert (const db::Box &box)
|
|||
|
||||
if (empty ()) {
|
||||
|
||||
m_polygons.insert (db::Polygon (box));
|
||||
mp_polygons->insert (db::Polygon (box));
|
||||
m_is_merged = true;
|
||||
update_bbox (box);
|
||||
|
||||
} else {
|
||||
|
||||
m_polygons.insert (db::Polygon (box));
|
||||
mp_polygons->insert (db::Polygon (box));
|
||||
m_is_merged = false;
|
||||
invalidate_cache ();
|
||||
|
||||
|
|
@ -434,7 +435,7 @@ void
|
|||
FlatRegion::insert (const db::Path &path)
|
||||
{
|
||||
if (path.points () > 0) {
|
||||
m_polygons.insert (path.polygon ());
|
||||
mp_polygons->insert (path.polygon ());
|
||||
m_is_merged = false;
|
||||
invalidate_cache ();
|
||||
}
|
||||
|
|
@ -444,7 +445,7 @@ void
|
|||
FlatRegion::insert (const db::Polygon &polygon)
|
||||
{
|
||||
if (polygon.holes () > 0 || polygon.vertices () > 0) {
|
||||
m_polygons.insert (polygon);
|
||||
mp_polygons->insert (polygon);
|
||||
m_is_merged = false;
|
||||
invalidate_cache ();
|
||||
}
|
||||
|
|
@ -456,7 +457,7 @@ FlatRegion::insert (const db::SimplePolygon &polygon)
|
|||
if (polygon.vertices () > 0) {
|
||||
db::Polygon poly;
|
||||
poly.assign_hull (polygon.begin_hull (), polygon.end_hull ());
|
||||
m_polygons.insert (poly);
|
||||
mp_polygons->insert (poly);
|
||||
m_is_merged = false;
|
||||
invalidate_cache ();
|
||||
}
|
||||
|
|
@ -468,7 +469,7 @@ FlatRegion::insert (const db::Shape &shape)
|
|||
if (shape.is_polygon () || shape.is_path () || shape.is_box ()) {
|
||||
db::Polygon poly;
|
||||
shape.polygon (poly);
|
||||
m_polygons.insert (poly);
|
||||
mp_polygons->insert (poly);
|
||||
m_is_merged = false;
|
||||
invalidate_cache ();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include "dbAsIfFlatRegion.h"
|
||||
#include "dbShapes.h"
|
||||
#include "dbShapes2.h"
|
||||
#include "tlCopyOnWrite.h"
|
||||
|
||||
namespace db {
|
||||
|
||||
|
|
@ -134,14 +135,16 @@ public:
|
|||
void transform (const Trans &trans)
|
||||
{
|
||||
if (! trans.is_unity ()) {
|
||||
for (polygon_iterator_type p = m_polygons.get_layer<db::Polygon, db::unstable_layer_tag> ().begin (); p != m_polygons.get_layer<db::Polygon, db::unstable_layer_tag> ().end (); ++p) {
|
||||
m_polygons.get_layer<db::Polygon, db::unstable_layer_tag> ().replace (p, p->transformed (trans));
|
||||
db::Shapes &polygons = *mp_polygons;
|
||||
for (polygon_iterator_type p = polygons.get_layer<db::Polygon, db::unstable_layer_tag> ().begin (); p != polygons.get_layer<db::Polygon, db::unstable_layer_tag> ().end (); ++p) {
|
||||
polygons.get_layer<db::Polygon, db::unstable_layer_tag> ().replace (p, p->transformed (trans));
|
||||
}
|
||||
invalidate_cache ();
|
||||
}
|
||||
}
|
||||
|
||||
db::Shapes &raw_polygons () { return m_polygons; }
|
||||
db::Shapes &raw_polygons () { return *mp_polygons; }
|
||||
const db::Shapes &raw_polygons () const { return *mp_polygons; }
|
||||
|
||||
protected:
|
||||
virtual void merged_semantics_changed ();
|
||||
|
|
@ -157,8 +160,8 @@ private:
|
|||
FlatRegion &operator= (const FlatRegion &other);
|
||||
|
||||
bool m_is_merged;
|
||||
mutable db::Shapes m_polygons;
|
||||
mutable db::Shapes m_merged_polygons;
|
||||
mutable tl::copy_on_write_ptr<db::Shapes> mp_polygons;
|
||||
mutable tl::copy_on_write_ptr<db::Shapes> mp_merged_polygons;
|
||||
mutable bool m_merged_polygons_valid;
|
||||
|
||||
void init ();
|
||||
|
|
|
|||
Loading…
Reference in New Issue