Centering of bounding box in fill tool - this allows using step vectors alone without a boundary layer

This commit is contained in:
Matthias Koefferlein 2021-03-06 00:31:05 +01:00
parent 07966baf71
commit 637968cbc4
7 changed files with 170 additions and 15 deletions

View File

@ -406,6 +406,73 @@ fill_region (db::Cell *cell, const db::Polygon &fp0, db::cell_index_type fill_ce
return fill_region (cell, fp0, fill_cell_index, fc_bbox.p1 () - db::Point (), db::Vector (fc_bbox.width (), 0), db::Vector (0, fc_bbox.height ()), origin, enhanced_fill, remaining_parts, fill_margin);
}
static db::Polygon
produce_fill_stripe (const db::Vector &row_step, const db::Vector &column_step, long n)
{
if (column_step.x () == 0) {
db::Coord ymin = std::min (0, row_step.y ());
db::Coord ymax = std::max (0, row_step.y ()) + n * column_step.y ();
return db::Polygon (db::Box (0, ymin, row_step.x (), ymax));
} else {
db::Coord xmin = 0;
db::Coord xmax = row_step.x ();
db::Coord ymin = 0;
db::Coord ymax = n * column_step.y ();
std::vector<db::Point> pts;
pts.reserve (n * 2);
for (long i = 0; i < n; ++i) {
db::Coord x = xmin + i * column_step.x ();
db::Coord y = i * column_step.y ();
if (i == 0) {
pts.push_back (db::Point (x, ymin));
} else {
pts.push_back (db::Point (x, y));
}
if (i == n - 1) {
pts.push_back (db::Point (x, ymax));
} else {
pts.push_back (db::Point (x, y + column_step.y ()));
}
}
for (long i = n; i > 0; ) {
--i;
db::Coord x = xmax + i * column_step.x ();
db::Coord y = i * column_step.y ();
if (i == n - 1) {
pts.push_back (db::Point (x, ymax));
} else {
pts.push_back (db::Point (x, y + column_step.y ()));
}
if (i == 0) {
pts.push_back (db::Point (x, ymin));
} else {
pts.push_back (db::Point (x, y));
}
}
db::Polygon p;
p.assign_hull (pts.begin (), pts.end ());
return p;
}
}
DB_PUBLIC bool
fill_region (db::Cell *cell, const db::Polygon &fp0, db::cell_index_type fill_cell_index, const db::Vector &kernel_origin, const db::Vector &row_step, const db::Vector &column_step, const db::Point &origin, bool enhanced_fill,
std::vector <db::Polygon> *remaining_parts, const db::Vector &fill_margin)
@ -502,17 +569,7 @@ fill_region (db::Cell *cell, const db::Polygon &fp0, db::cell_index_type fill_ce
cell->insert (array);
if (remaining_parts) {
db::Point fill_stripe[4] = {
db::Point () + p0 + kernel_origin,
db::Point () + p0 + kernel_origin + column_step * long (jj - j),
db::Point () + p0 + kernel_origin + column_step * long (jj - j) + row_step,
db::Point () + p0 + kernel_origin + row_step
};
filled_regions.push_back (db::Polygon ());
filled_regions.back ().assign_hull (fill_stripe, fill_stripe + 4);
filled_regions.push_back (produce_fill_stripe (row_step, column_step, long (jj - j)).moved (p0 + kernel_origin));
}
any_fill = true;

View File

@ -115,3 +115,101 @@ TEST(3)
db::compare_layouts (_this, ly, tl::testsrc () + "/testdata/algo/fill_tool_au3.gds");
}
TEST(3a)
{
db::Layout ly;
{
std::string fn (tl::testsrc ());
fn += "/testdata/algo/fill_tool3.gds";
tl::InputStream stream (fn);
db::Reader reader (stream);
reader.read (ly);
}
db::cell_index_type fill_cell = ly.cell_by_name ("FILL_CELL").second;
db::cell_index_type top_cell = ly.cell_by_name ("TOP").second;
unsigned int fill_layer = ly.get_layer (db::LayerProperties (1, 0));
db::Region fill_region (db::RecursiveShapeIterator (ly, ly.cell (top_cell), fill_layer));
db::Region remaining_parts, remaining_polygons;
db::Vector ko (-100, -130);
db::Vector rs (230, 40);
db::Vector cs (-40, 230);
db::fill_region (&ly.cell (top_cell), fill_region, fill_cell, ko, rs, cs, db::Point (), true, &remaining_parts, db::Vector (50, 100), &remaining_polygons);
unsigned int l100 = ly.insert_layer (db::LayerProperties (100, 0));
unsigned int l101 = ly.insert_layer (db::LayerProperties (101, 0));
remaining_parts.insert_into (&ly, top_cell, l100);
remaining_polygons.insert_into (&ly, top_cell, l101);
CHECKPOINT();
db::compare_layouts (_this, ly, tl::testsrc () + "/testdata/algo/fill_tool_au3a.gds");
}
TEST(3b)
{
db::Layout ly;
{
std::string fn (tl::testsrc ());
fn += "/testdata/algo/fill_tool3.gds";
tl::InputStream stream (fn);
db::Reader reader (stream);
reader.read (ly);
}
db::cell_index_type fill_cell = ly.cell_by_name ("FILL_CELL").second;
db::cell_index_type top_cell = ly.cell_by_name ("TOP").second;
unsigned int fill_layer = ly.get_layer (db::LayerProperties (1, 0));
db::Region fill_region (db::RecursiveShapeIterator (ly, ly.cell (top_cell), fill_layer));
db::Region remaining_parts, remaining_polygons;
db::Vector ko (-100, -130);
db::Vector rs (230, -40);
db::Vector cs (40, 230);
db::fill_region (&ly.cell (top_cell), fill_region, fill_cell, ko, rs, cs, db::Point (), true, &remaining_parts, db::Vector (50, 100), &remaining_polygons);
unsigned int l100 = ly.insert_layer (db::LayerProperties (100, 0));
unsigned int l101 = ly.insert_layer (db::LayerProperties (101, 0));
remaining_parts.insert_into (&ly, top_cell, l100);
remaining_polygons.insert_into (&ly, top_cell, l101);
CHECKPOINT();
db::compare_layouts (_this, ly, tl::testsrc () + "/testdata/algo/fill_tool_au3b.gds");
}
TEST(3c)
{
db::Layout ly;
{
std::string fn (tl::testsrc ());
fn += "/testdata/algo/fill_tool3.gds";
tl::InputStream stream (fn);
db::Reader reader (stream);
reader.read (ly);
}
db::cell_index_type fill_cell = ly.cell_by_name ("FILL_CELL").second;
db::cell_index_type top_cell = ly.cell_by_name ("TOP").second;
unsigned int fill_layer = ly.get_layer (db::LayerProperties (1, 0));
db::Region fill_region (db::RecursiveShapeIterator (ly, ly.cell (top_cell), fill_layer));
db::Region remaining_parts, remaining_polygons;
db::Vector ko (-100, -130);
db::Vector rs (230, -40);
db::Vector cs (-40, 230);
db::fill_region (&ly.cell (top_cell), fill_region, fill_cell, ko, rs, cs, db::Point (), true, &remaining_parts, db::Vector (50, 100), &remaining_polygons);
unsigned int l100 = ly.insert_layer (db::LayerProperties (100, 0));
unsigned int l101 = ly.insert_layer (db::LayerProperties (101, 0));
remaining_parts.insert_into (&ly, top_cell, l100);
remaining_polygons.insert_into (&ly, top_cell, l101);
CHECKPOINT();
db::compare_layouts (_this, ly, tl::testsrc () + "/testdata/algo/fill_tool_au3c.gds");
}

View File

@ -240,7 +240,7 @@ BEGIN_PROTECTED
db::Coord distance_y = db::coord_traits<db::Coord>::rounded (y / cv->layout ().dbu ());
// read fill cell margin
db::Vector fill_margin (exclude_x, exclude_y);
db::Vector fill_margin;
x = 0.0, y = 0.0;
s = tl::to_string (fill_margin_le->text ());
ex = tl::Extractor (s.c_str ());
@ -254,7 +254,7 @@ BEGIN_PROTECTED
}
// read fill cell 2 margin
db::Vector fill2_margin (exclude_x, exclude_y);
db::Vector fill2_margin;
x = 0.0, y = 0.0;
s = tl::to_string (fill2_margin_le->text ());
ex = tl::Extractor (s.c_str ());
@ -525,9 +525,9 @@ BEGIN_PROTECTED
}
db::Vector rs (row_dx, row_dy), cs (column_dx, column_dy);
db::Vector ko = fc_bbox.center () - db::Point () - (rs + cs) / 2;
db::Vector ko = fc_bbox.center () - db::Point (row_dx / 2, column_dy / 2);
bool any_fill = fill_region (cv.cell (), *fp0, fill_cell->cell_index (), ko, rs, cs, fr_bbox.center (), enhanced_fill, (enhanced_fill || fill_cell2) ? &new_fill_area : 0, fill_margin);
bool any_fill = fill_region (cv.cell (), *fp0, fill_cell->cell_index (), ko, rs, cs, fr_bbox.p1 (), enhanced_fill, (enhanced_fill || fill_cell2) ? &new_fill_area : 0, fill_margin);
if (! any_fill) {
non_filled_area.push_back (*fp0);
}

Binary file not shown.

BIN
testdata/algo/fill_tool_au3a.gds vendored Normal file

Binary file not shown.

BIN
testdata/algo/fill_tool_au3b.gds vendored Normal file

Binary file not shown.

BIN
testdata/algo/fill_tool_au3c.gds vendored Normal file

Binary file not shown.