WIP: polygons to edges with properties

This commit is contained in:
Matthias Koefferlein 2023-01-17 19:07:32 +01:00
parent 8fb4e36809
commit 40267dddb6
12 changed files with 209 additions and 25 deletions

View File

@ -960,10 +960,15 @@ AsIfFlatEdges::insert_into (Layout *layout, db::cell_index_type into_cell, unsig
{
// improves performance when inserting an original layout into the same layout
db::LayoutLocker locker (layout);
db::PropertyMapper pm (&layout->properties_repository (), properties_repository ());
db::Shapes &shapes = layout->cell (into_cell).shapes (into_layer);
for (EdgesIterator e (begin ()); ! e.at_end (); ++e) {
shapes.insert (*e);
if (e.prop_id () != 0) {
shapes.insert (db::EdgeWithProperties (*e, pm (e.prop_id ())));
} else {
shapes.insert (*e);
}
}
}

View File

@ -130,6 +130,7 @@ EdgesDelegate *
AsIfFlatRegion::edges (const EdgeFilterBase *filter) const
{
std::unique_ptr<FlatEdges> result (new FlatEdges ());
db::PropertyMapper pm (result->properties_repository (), properties_repository ());
size_t n = 0;
for (RegionIterator p (begin_merged ()); ! p.at_end (); ++p) {
@ -138,10 +139,11 @@ AsIfFlatRegion::edges (const EdgeFilterBase *filter) const
result->reserve (n);
for (RegionIterator p (begin_merged ()); ! p.at_end (); ++p) {
db::properties_id_type prop_id = p.prop_id ();
for (db::Polygon::polygon_edge_iterator e = p->begin_edge (); ! e.at_end (); ++e) {
if (! filter || filter->selected (*e)) {
if (p.prop_id () != 0) {
result->insert (db::EdgeWithProperties (*e, p.prop_id ()));
if (prop_id != 0) {
result->insert (db::EdgeWithProperties (*e, pm (prop_id)));
} else {
result->insert (*e);
}
@ -1707,7 +1709,7 @@ AsIfFlatRegion::xor_with (const Region &other, PropertyConstraint prop_constrain
}
RegionDelegate *
AsIfFlatRegion::or_with (const Region &other, PropertyConstraint prop_constraint) const
AsIfFlatRegion::or_with (const Region &other, PropertyConstraint /*prop_constraint*/) const
{
if (empty () && ! other.strict_handling ()) {
@ -1807,10 +1809,15 @@ AsIfFlatRegion::insert_into (Layout *layout, db::cell_index_type into_cell, unsi
{
// improves performance when inserting an original layout into the same layout
db::LayoutLocker locker (layout);
db::PropertyMapper pm (&layout->properties_repository (), properties_repository ());
db::Shapes &shapes = layout->cell (into_cell).shapes (into_layer);
for (RegionIterator p (begin ()); ! p.at_end (); ++p) {
shapes.insert (*p);
if (p.prop_id () != 0) {
shapes.insert (db::PolygonWithProperties (*p, pm (p.prop_id ())));
} else {
shapes.insert (*p);
}
}
}

View File

@ -219,12 +219,17 @@ void DeepEdges::merged_semantics_changed ()
// .. nothing yet ..
}
void DeepEdges::do_insert (const db::Edge &edge)
void DeepEdges::do_insert (const db::Edge &edge, db::properties_id_type prop_id)
{
db::Layout &layout = deep_layer ().layout ();
if (layout.begin_top_down () != layout.end_top_down ()) {
db::Cell &top_cell = layout.cell (*layout.begin_top_down ());
top_cell.shapes (deep_layer ().layer ()).insert (edge);
db::Shapes &shapes = top_cell.shapes (deep_layer ().layer ());
if (prop_id == 0) {
shapes.insert (edge);
} else {
shapes.insert (db::EdgeWithProperties (edge, prop_id));
}
}
invalidate_bbox ();

View File

@ -62,7 +62,7 @@ public:
virtual void reserve (size_t n);
virtual void do_insert (const db::Edge &edge);
virtual void do_insert (const db::Edge &edge, properties_id_type prop_id);
EdgesDelegate *clone () const;

View File

@ -88,7 +88,8 @@ 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 (*mp_edges);
db::PropertyMapper pm (&layout->properties_repository (), mp_properties_repository.get_const ());
layout->cell (into_cell).shapes (into_layer).insert (*mp_edges, pm);
}
void FlatEdges::merged_semantics_changed ()
@ -355,11 +356,16 @@ const db::PropertiesRepository *FlatEdges::properties_repository () const
}
void
FlatEdges::do_insert (const db::Edge &edge)
FlatEdges::do_insert (const db::Edge &edge, db::properties_id_type prop_id)
{
m_is_merged = empty ();
mp_edges->insert (edge);
if (prop_id == 0) {
mp_edges->insert (edge);
} else {
mp_edges->insert (db::EdgeWithProperties (edge, prop_id));
}
invalidate_cache ();
}

View File

@ -96,7 +96,7 @@ public:
virtual db::PropertiesRepository *properties_repository ();
virtual const db::PropertiesRepository *properties_repository () const;
void do_insert (const db::Edge &edge);
void do_insert (const db::Edge &edge, properties_id_type prop_id);
void do_transform (const db::Trans &t)
{

View File

@ -50,10 +50,21 @@ void
MutableEdges::insert (const db::Box &box)
{
if (! box.empty () && box.width () > 0 && box.height () > 0) {
do_insert (db::Edge (box.lower_left (), box.upper_left ()));
do_insert (db::Edge (box.upper_left (), box.upper_right ()));
do_insert (db::Edge (box.upper_right (), box.lower_right ()));
do_insert (db::Edge (box.lower_right (), box.lower_left ()));
do_insert (db::Edge (box.lower_left (), box.upper_left ()), 0);
do_insert (db::Edge (box.upper_left (), box.upper_right ()), 0);
do_insert (db::Edge (box.upper_right (), box.lower_right ()), 0);
do_insert (db::Edge (box.lower_right (), box.lower_left ()), 0);
}
}
void
MutableEdges::insert (const db::BoxWithProperties &box)
{
if (! box.empty () && box.width () > 0 && box.height () > 0) {
do_insert (db::Edge (box.lower_left (), box.upper_left ()), box.properties_id ());
do_insert (db::Edge (box.upper_left (), box.upper_right ()), box.properties_id ());
do_insert (db::Edge (box.upper_right (), box.lower_right ()), box.properties_id ());
do_insert (db::Edge (box.lower_right (), box.lower_left ()), box.properties_id ());
}
}
@ -65,12 +76,30 @@ MutableEdges::insert (const db::Path &path)
}
}
void
MutableEdges::insert (const db::PathWithProperties &path)
{
if (path.points () > 0) {
insert (db::PolygonWithProperties (path.polygon (), path.properties_id ()));
}
}
void
MutableEdges::insert (const db::Polygon &polygon)
{
if (polygon.holes () > 0 || polygon.vertices () > 0) {
for (db::Polygon::polygon_edge_iterator e = polygon.begin_edge (); ! e.at_end (); ++e) {
do_insert (*e);
do_insert (*e, 0);
}
}
}
void
MutableEdges::insert (const db::PolygonWithProperties &polygon)
{
if (polygon.holes () > 0 || polygon.vertices () > 0) {
for (db::Polygon::polygon_edge_iterator e = polygon.begin_edge (); ! e.at_end (); ++e) {
do_insert (*e, polygon.properties_id ());
}
}
}
@ -80,7 +109,17 @@ MutableEdges::insert (const db::SimplePolygon &polygon)
{
if (polygon.vertices () > 0) {
for (db::SimplePolygon::polygon_edge_iterator e = polygon.begin_edge (); ! e.at_end (); ++e) {
do_insert (*e);
do_insert (*e, 0);
}
}
}
void
MutableEdges::insert (const db::SimplePolygonWithProperties &polygon)
{
if (polygon.vertices () > 0) {
for (db::SimplePolygon::polygon_edge_iterator e = polygon.begin_edge (); ! e.at_end (); ++e) {
do_insert (*e, polygon.properties_id ());
}
}
}
@ -88,17 +127,21 @@ MutableEdges::insert (const db::SimplePolygon &polygon)
void
MutableEdges::insert (const db::Shape &shape)
{
db::properties_id_type prop_id = shape.prop_id ();
if (shape.is_polygon () || shape.is_path () || shape.is_box ()) {
db::Polygon poly;
shape.polygon (poly);
insert (poly);
for (auto e = poly.begin_edge (); ! e.at_end (); ++e) {
do_insert (*e, prop_id);
}
} else if (shape.is_edge ()) {
db::Edge edge;
shape.edge (edge);
do_insert (edge);
do_insert (edge, prop_id);
}
}

View File

@ -54,7 +54,7 @@ public:
virtual void reserve (size_t n) = 0;
virtual void do_insert (const db::Edge &edge) = 0;
virtual void do_insert (const db::Edge &edge, db::properties_id_type prop_id) = 0;
void transform (const db::UnitTrans &) { }
void transform (const db::Disp &t) { do_transform (db::Trans (t)); }
@ -63,29 +63,37 @@ public:
void transform (const db::IMatrix2d &t) { do_transform (t); }
void transform (const db::IMatrix3d &t) { do_transform (t); }
void insert (const db::Edge &edge) { do_insert (edge); }
void insert (const db::Edge &edge) { do_insert (edge, 0); }
void insert (const db::EdgeWithProperties &edge) { do_insert (edge, edge.properties_id ()); }
void insert (const db::Box &box);
void insert (const db::BoxWithProperties &box);
void insert (const db::Path &path);
void insert (const db::PathWithProperties &path);
void insert (const db::SimplePolygon &polygon);
void insert (const db::SimplePolygonWithProperties &polygon);
void insert (const db::Polygon &polygon);
void insert (const db::PolygonWithProperties &polygon);
void insert (const db::Shape &shape);
template <class T>
void insert (const db::Shape &shape, const T &trans)
{
db::properties_id_type prop_id = shape.prop_id ();
if (shape.is_polygon () || shape.is_path () || shape.is_box ()) {
db::Polygon poly;
shape.polygon (poly);
poly.transform (trans);
insert (poly);
for (auto e = poly.begin_edge (); ! e.at_end (); ++e) {
do_insert ((*e).transformed (trans), prop_id);
}
} else if (shape.is_edge ()) {
db::Edge edge;
shape.edge (edge);
edge.transform (trans);
insert (edge);
do_insert (edge, prop_id);
}
}

View File

@ -1716,3 +1716,57 @@ TEST(40_BoolWithProperties)
db::compare_layouts (_this, target, tl::testdata () + "/algo/flat_region_au40.gds");
}
TEST(41_EdgesWithProperties)
{
db::Layout ly;
{
std::string fn (tl::testdata ());
fn += "/algo/deep_region_40.gds";
tl::InputStream stream (fn);
db::Reader reader (stream);
reader.read (ly);
}
db::cell_index_type top_cell_index = *ly.begin_top_down ();
db::Cell &top_cell = ly.cell (top_cell_index);
unsigned int l1 = ly.get_layer (db::LayerProperties (1, 0));
unsigned int l2 = ly.get_layer (db::LayerProperties (2, 0));
unsigned int l3 = ly.get_layer (db::LayerProperties (3, 0)); // empty
db::RecursiveShapeIterator si1 (ly, top_cell, l1);
si1.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties);
db::Region r1wp (si1);
db::Region r1wp_nomerge = r1wp;
r1wp_nomerge.set_merged_semantics (false);
si1.shape_flags (db::ShapeIterator::All);
db::Region r1 (si1);
db::RecursiveShapeIterator si2 (ly, top_cell, l2);
si2.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties);
db::Region r2wp (si2);
db::Region r2wp_nomerge = r2wp;
r2wp_nomerge.set_merged_semantics (false);
si2.shape_flags (db::ShapeIterator::All);
db::Region r2 (si2);
db::Layout target;
unsigned int target_top_cell_index = target.add_cell (ly.cell_name (top_cell_index));
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (1, 0)), r1wp);
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (2, 0)), r2wp);
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (10, 0)), r1.edges ());
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (11, 0)), r1wp.edges ());
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (12, 0)), r1wp_nomerge.edges ());
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (20, 0)), r2.edges ());
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (21, 0)), r2wp.edges ());
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (22, 0)), r2wp_nomerge.edges ());
CHECKPOINT();
db::compare_layouts (_this, target, tl::testdata () + "/algo/flat_region_au41.gds");
}

View File

@ -2204,6 +2204,62 @@ TEST(40_BoolWithProperties)
db::compare_layouts (_this, target, tl::testdata () + "/algo/deep_region_au40.gds");
}
TEST(41_EdgesWithProperties)
{
db::Layout ly;
{
std::string fn (tl::testdata ());
fn += "/algo/deep_region_40.gds";
tl::InputStream stream (fn);
db::Reader reader (stream);
reader.read (ly);
}
db::cell_index_type top_cell_index = *ly.begin_top_down ();
db::Cell &top_cell = ly.cell (top_cell_index);
db::DeepShapeStore dss;
unsigned int l1 = ly.get_layer (db::LayerProperties (1, 0));
unsigned int l2 = ly.get_layer (db::LayerProperties (2, 0));
unsigned int l3 = ly.get_layer (db::LayerProperties (3, 0)); // empty
db::RecursiveShapeIterator si1 (ly, top_cell, l1);
si1.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties);
db::Region r1wp (si1, dss);
db::Region r1wp_nomerge = r1wp;
r1wp_nomerge.set_merged_semantics (false);
si1.shape_flags (db::ShapeIterator::All);
db::Region r1 (si1, dss);
db::RecursiveShapeIterator si2 (ly, top_cell, l2);
si2.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties);
db::Region r2wp (si2, dss);
db::Region r2wp_nomerge = r2wp;
r2wp_nomerge.set_merged_semantics (false);
si2.shape_flags (db::ShapeIterator::All);
db::Region r2 (si2, dss);
db::Layout target;
unsigned int target_top_cell_index = target.add_cell (ly.cell_name (top_cell_index));
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (1, 0)), r1wp);
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (2, 0)), r2wp);
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (10, 0)), r1.edges ());
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (11, 0)), r1wp.edges ());
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (12, 0)), r1wp_nomerge.edges ());
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (20, 0)), r2.edges ());
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (21, 0)), r2wp.edges ());
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (22, 0)), r2wp_nomerge.edges ());
CHECKPOINT();
db::compare_layouts (_this, target, tl::testdata () + "/algo/deep_region_au41.gds");
}
TEST(100_Integration)
{
db::Layout ly;

BIN
testdata/algo/deep_region_au41.gds vendored Normal file

Binary file not shown.

BIN
testdata/algo/flat_region_au41.gds vendored Normal file

Binary file not shown.