diff --git a/src/db/db/dbFillTool.cc b/src/db/db/dbFillTool.cc index 0c60f8c64..bf8abba3e 100644 --- a/src/db/db/dbFillTool.cc +++ b/src/db/db/dbFillTool.cc @@ -77,6 +77,16 @@ public: return (unsigned int) m_area_maps.size (); } + int index_for_p0 (const db::Point &p0) const + { + for (auto i = m_area_maps.begin (); i != m_area_maps.end (); ++i) { + if (i->p0 () == p0) { + return int (i - m_area_maps.begin ()); + } + } + return -1; + } + const db::AreaMap &area_map (unsigned int i) const { return m_area_maps [i]; @@ -212,8 +222,10 @@ create_instances (GenericRasterizer &am, db::Cell *cell, db::cell_index_type fil db::AreaMap &am1 = am.area_map (i); const db::AreaMap *am1_excl = 0; if (exclude_rasterized) { - tl_assert (i < exclude_rasterized->area_maps ()); - am1_excl = &exclude_rasterized->area_map (i); + int ie = exclude_rasterized->index_for_p0 (am1.p0 ()); + if (ie >= 0) { + am1_excl = &exclude_rasterized->area_map (ie); + } } size_t nx = am1.nx (); @@ -316,6 +328,7 @@ fill_polygon_impl (db::Cell *cell, const db::Polygon &fp0, db::cell_index_type f db::Box rasterized_area = fp0.box (); std::unique_ptr exclude_rasterized; + bool has_exclude_area = false; if (! exclude_area.empty ()) { @@ -334,25 +347,31 @@ fill_polygon_impl (db::Cell *cell, const db::Polygon &fp0, db::cell_index_type f excluded.size (-dy, 0); excluded.merge (); - if (enhanced_fill || remaining_parts != 0) { + if (! excluded.empty ()) { - // In enhanced fill or if the remaining parts are requested, it is better to implement the - // exclude area by a boolean NOT - fr -= excluded; + has_exclude_area = true; - } else { + if (enhanced_fill || remaining_parts != 0) { - // Otherwise use a second rasterizer for the exclude polygons that must have a zero pixel coverage for the - // pixel to be filled. + // In enhanced fill or if the remaining parts are requested, it is better to implement the + // exclude area by a boolean NOT + fr -= excluded; + + } else { + + // Otherwise use a second rasterizer for the exclude polygons that must have a zero pixel coverage for the + // pixel to be filled. + + std::vector excluded_poly; + excluded_poly.reserve (excluded.count ()); + for (auto i = excluded.begin (); ! i.at_end (); ++i) { + excluded_poly.push_back (*i); + } + excluded.clear (); + + exclude_rasterized.reset (new GenericRasterizer (excluded_poly, rasterized_area, row_step, column_step, origin, fc_bbox.p2 () - fc_bbox.p1 ())); - std::vector excluded_poly; - excluded_poly.reserve (excluded.count ()); - for (auto i = excluded.begin (); ! i.at_end (); ++i) { - excluded_poly.push_back (*i); } - excluded.clear (); - - exclude_rasterized.reset (new GenericRasterizer (excluded_poly, rasterized_area, row_step, column_step, origin, fc_bbox.p2 () - fc_bbox.p1 ())); } @@ -388,14 +407,14 @@ fill_polygon_impl (db::Cell *cell, const db::Polygon &fp0, db::cell_index_type f fr.clear (); - if (filled_poly.empty ()) { - return false; - } - std::vector filled_regions; bool any_fill = false; - if (exclude_rasterized.get ()) { + if (filled_poly.empty ()) { + + // not need to do anything + + } else if (exclude_rasterized.get ()) { tl_assert (remaining_parts == 0); GenericRasterizer am (filled_poly, rasterized_area, row_step, column_step, origin, fc_bbox.p2 () - fc_bbox.p1 ()); @@ -447,7 +466,7 @@ fill_polygon_impl (db::Cell *cell, const db::Polygon &fp0, db::cell_index_type f } - if (any_fill) { + if (any_fill || has_exclude_area) { if (remaining_parts) { db::EdgeProcessor ep; diff --git a/src/drc/unit_tests/drcSimpleTests.cc b/src/drc/unit_tests/drcSimpleTests.cc index 258c5969d..6ccccb378 100644 --- a/src/drc/unit_tests/drcSimpleTests.cc +++ b/src/drc/unit_tests/drcSimpleTests.cc @@ -1453,6 +1453,16 @@ TEST(47bd_fillWithUsingOutputDeep) run_test (_this, "47b", true); } +TEST(47c_fillWithExcludeArea) +{ + run_test (_this, "47c", false); +} + +TEST(47cd_fillWithExcludeAreaDeep) +{ + run_test (_this, "47c", true); +} + TEST(48_drcWithFragments) { run_test (_this, "48", false); diff --git a/testdata/drc/drcSimpleTests_47c.drc b/testdata/drc/drcSimpleTests_47c.drc new file mode 100644 index 000000000..b2b9b1f41 --- /dev/null +++ b/testdata/drc/drcSimpleTests_47c.drc @@ -0,0 +1,21 @@ + +source $drc_test_source +target $drc_test_target + +if $drc_test_deep + deep +end + +l1 = input(1, 0) +l2 = input(2, 0) + +p = fill_pattern("PAT1").shape(100, 0, box(0, 0, 5.um, 5.um)).origin(-2.5.um, -2.5.um) +l1.fill(p, hstep(10.0, 5.0), vstep(-5.0, 10.0), fill_exclude(l2)) + +p = fill_pattern("PAT1").shape(110, 0, box(0, 0, 5.um, 5.um)).origin(-2.5.um, -2.5.um) +left = l1.fill_with_left(p, hstep(10.0, 5.0), vstep(-5.0, 10.0), fill_exclude(l2)) + +l1.output(1, 0) +l2.output(2, 0) +left.output(111, 0) + diff --git a/testdata/drc/drcSimpleTests_47c.gds b/testdata/drc/drcSimpleTests_47c.gds new file mode 100644 index 000000000..5bcf8d5a7 Binary files /dev/null and b/testdata/drc/drcSimpleTests_47c.gds differ diff --git a/testdata/drc/drcSimpleTests_au47c.gds b/testdata/drc/drcSimpleTests_au47c.gds new file mode 100644 index 000000000..b90559474 Binary files /dev/null and b/testdata/drc/drcSimpleTests_au47c.gds differ diff --git a/testdata/drc/drcSimpleTests_au47cd.gds b/testdata/drc/drcSimpleTests_au47cd.gds new file mode 100644 index 000000000..bb300a375 Binary files /dev/null and b/testdata/drc/drcSimpleTests_au47cd.gds differ