Bugfixing new implementation of fill tool, added tests for DRC implementation

This commit is contained in:
Matthias Koefferlein 2025-09-06 22:28:01 +02:00
parent 810f5fb8aa
commit cd34125b0c
6 changed files with 72 additions and 22 deletions

View File

@ -77,6 +77,16 @@ public:
return (unsigned int) m_area_maps.size (); 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 const db::AreaMap &area_map (unsigned int i) const
{ {
return m_area_maps [i]; 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); db::AreaMap &am1 = am.area_map (i);
const db::AreaMap *am1_excl = 0; const db::AreaMap *am1_excl = 0;
if (exclude_rasterized) { if (exclude_rasterized) {
tl_assert (i < exclude_rasterized->area_maps ()); int ie = exclude_rasterized->index_for_p0 (am1.p0 ());
am1_excl = &exclude_rasterized->area_map (i); if (ie >= 0) {
am1_excl = &exclude_rasterized->area_map (ie);
}
} }
size_t nx = am1.nx (); 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 (); db::Box rasterized_area = fp0.box ();
std::unique_ptr<GenericRasterizer> exclude_rasterized; std::unique_ptr<GenericRasterizer> exclude_rasterized;
bool has_exclude_area = false;
if (! exclude_area.empty ()) { 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.size (-dy, 0);
excluded.merge (); 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 has_exclude_area = true;
// exclude area by a boolean NOT
fr -= excluded;
} 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 // In enhanced fill or if the remaining parts are requested, it is better to implement the
// pixel to be filled. // 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<db::Polygon> 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<db::Polygon> 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 (); fr.clear ();
if (filled_poly.empty ()) {
return false;
}
std::vector <db::Polygon> filled_regions; std::vector <db::Polygon> filled_regions;
bool any_fill = false; 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); tl_assert (remaining_parts == 0);
GenericRasterizer am (filled_poly, rasterized_area, row_step, column_step, origin, fc_bbox.p2 () - fc_bbox.p1 ()); 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) { if (remaining_parts) {
db::EdgeProcessor ep; db::EdgeProcessor ep;

View File

@ -1453,6 +1453,16 @@ TEST(47bd_fillWithUsingOutputDeep)
run_test (_this, "47b", true); run_test (_this, "47b", true);
} }
TEST(47c_fillWithExcludeArea)
{
run_test (_this, "47c", false);
}
TEST(47cd_fillWithExcludeAreaDeep)
{
run_test (_this, "47c", true);
}
TEST(48_drcWithFragments) TEST(48_drcWithFragments)
{ {
run_test (_this, "48", false); run_test (_this, "48", false);

21
testdata/drc/drcSimpleTests_47c.drc vendored Normal file
View File

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

BIN
testdata/drc/drcSimpleTests_47c.gds vendored Normal file

Binary file not shown.

BIN
testdata/drc/drcSimpleTests_au47c.gds vendored Normal file

Binary file not shown.

BIN
testdata/drc/drcSimpleTests_au47cd.gds vendored Normal file

Binary file not shown.