diff --git a/src/db/db/dbFillTool.cc b/src/db/db/dbFillTool.cc index a9024b201..5845bde85 100644 --- a/src/db/db/dbFillTool.cc +++ b/src/db/db/dbFillTool.cc @@ -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 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 *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; diff --git a/src/db/unit_tests/dbFillToolTests.cc b/src/db/unit_tests/dbFillToolTests.cc index de3fa628b..9bade38cf 100644 --- a/src/db/unit_tests/dbFillToolTests.cc +++ b/src/db/unit_tests/dbFillToolTests.cc @@ -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"); +} diff --git a/src/lay/lay/layFillDialog.cc b/src/lay/lay/layFillDialog.cc index 6503a453c..f34ad0f80 100644 --- a/src/lay/lay/layFillDialog.cc +++ b/src/lay/lay/layFillDialog.cc @@ -240,7 +240,7 @@ BEGIN_PROTECTED db::Coord distance_y = db::coord_traits::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); } diff --git a/testdata/algo/fill_tool_au3.gds b/testdata/algo/fill_tool_au3.gds index 3d351b309..7d6e50a8e 100644 Binary files a/testdata/algo/fill_tool_au3.gds and b/testdata/algo/fill_tool_au3.gds differ diff --git a/testdata/algo/fill_tool_au3a.gds b/testdata/algo/fill_tool_au3a.gds new file mode 100644 index 000000000..edddbc81f Binary files /dev/null and b/testdata/algo/fill_tool_au3a.gds differ diff --git a/testdata/algo/fill_tool_au3b.gds b/testdata/algo/fill_tool_au3b.gds new file mode 100644 index 000000000..08057877c Binary files /dev/null and b/testdata/algo/fill_tool_au3b.gds differ diff --git a/testdata/algo/fill_tool_au3c.gds b/testdata/algo/fill_tool_au3c.gds new file mode 100644 index 000000000..d06da14a0 Binary files /dev/null and b/testdata/algo/fill_tool_au3c.gds differ