WIP: copy-on-write for FlatRegion and FlatEdges too

This commit is contained in:
Matthias Koefferlein 2020-12-27 19:19:09 +01:00
parent cc58d7d8ee
commit cdcac6f5d3
4 changed files with 113 additions and 99 deletions

View File

@ -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 ();
}

View File

@ -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 ();

View File

@ -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 ();
}

View File

@ -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 ();