mirror of https://github.com/KLayout/klayout.git
WIP
This commit is contained in:
parent
d76fc02244
commit
7bd4a692d8
|
|
@ -323,11 +323,69 @@ rasterize_extended (const db::Polygon &fp, const db::Box &fc_bbox, db::AreaMap &
|
|||
return false;
|
||||
}
|
||||
|
||||
am.reinitialize (fp_bbox.p1 (), db::Vector (dx, dy), size_t (nx), size_t (ny));
|
||||
// @@@
|
||||
// try to create a point for which the fill box is inside the polygon
|
||||
size_t nhull = fp.hull ().size ();
|
||||
if (nhull < 3) {
|
||||
return false;
|
||||
}
|
||||
|
||||
db::Point p0 = fp.hull ()[0];
|
||||
db::Point p1 = fp.hull ()[1];
|
||||
db::Point pm1 = fp.hull ()[nhull - 1];
|
||||
|
||||
db::Coord hx = (dx + 1) / 2;
|
||||
db::Coord hy = (dy + 1) / 2;
|
||||
|
||||
db::Edge e1 (p0, p1);
|
||||
if (e1.dx () < 0) {
|
||||
e1.move (db::Vector (hx, hy));
|
||||
} else {
|
||||
e1.move (db::Vector (hx, -hy));
|
||||
}
|
||||
|
||||
db::Edge em1 (p0, pm1);
|
||||
if (em1.dy () < 0) {
|
||||
em1.move (db::Vector (hx, hy));
|
||||
} else {
|
||||
em1.move (db::Vector (-hx, hy));
|
||||
}
|
||||
|
||||
std::pair<bool, db::Point> cp = e1.cut_point (em1);
|
||||
|
||||
db::Point o = fp_bbox.p1 ();
|
||||
if (cp.first) {
|
||||
db::Point po = cp.second - db::Vector (hx, hy);
|
||||
o = po - db::Vector (dx * ((po.x () - fp_bbox.p1 ().x ()) / dx), dy * ((po.y () - fp_bbox.p1 ().y ()) / dy));
|
||||
}
|
||||
|
||||
printf("@@@ fp=%s\n", fp.to_string().c_str()); fflush(stdout); // @@@
|
||||
printf("@@@ -> o=%s\n", o.to_string().c_str()); fflush(stdout); // @@@
|
||||
// @@@
|
||||
|
||||
am.reinitialize (o, db::Vector (dx, dy), size_t (nx), size_t (ny));
|
||||
|
||||
// Rasterize to determine fill regions
|
||||
db::rasterize (fp, am);
|
||||
|
||||
// @@@
|
||||
{
|
||||
db::Coord nx = db::Coord (am.nx ());
|
||||
db::Coord ny = db::Coord (am.ny ());
|
||||
db::AreaMap::area_type amax = am.pixel_area ();
|
||||
double n = 0;
|
||||
for (size_t i = 0; i < size_t (nx); ++i) {
|
||||
for (size_t j = 0; j < size_t (ny); ++j) {
|
||||
if (am.get (i, j) >= amax) {
|
||||
n += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("@@@ -> n=%d\n", int(n)); fflush(stdout); // @@@
|
||||
}
|
||||
// @@@
|
||||
return true; // @@@
|
||||
|
||||
if (tl::verbosity () >= 50) {
|
||||
|
||||
db::Coord nx = db::Coord (am.nx ());
|
||||
|
|
@ -356,7 +414,6 @@ rasterize_extended (const db::Polygon &fp, const db::Box &fc_bbox, db::AreaMap &
|
|||
|
||||
am.move (d);
|
||||
am.clear ();
|
||||
|
||||
db::rasterize (fp, am);
|
||||
|
||||
if (tl::verbosity () >= 50) {
|
||||
|
|
@ -501,7 +558,7 @@ fill_region (db::Cell *cell, const db::Polygon &fp0, db::cell_index_type fill_ce
|
|||
|
||||
std::vector <db::Polygon> fpa;
|
||||
std::vector <db::Polygon> fpb;
|
||||
fpa.push_back (fp0.transformed (shear));
|
||||
fpa.push_back (fp0);
|
||||
|
||||
ep.size (fpa, -dx, 0, fpb, 3 /*mode*/, false /*=don't resolve holes*/);
|
||||
fpa.swap (fpb);
|
||||
|
|
@ -524,7 +581,9 @@ fill_region (db::Cell *cell, const db::Polygon &fp0, db::cell_index_type fill_ce
|
|||
filled_regions.clear ();
|
||||
bool any_fill = false;
|
||||
|
||||
for (std::vector <db::Polygon>::const_iterator fp = fpb.begin (); fp != fpb.end (); ++fp) {
|
||||
for (std::vector <db::Polygon>::const_iterator fpr = fpb.begin (); fpr != fpb.end (); ++fpr) {
|
||||
|
||||
db::Polygon fp = fpr->transformed (shear);
|
||||
|
||||
size_t ninsts = 0;
|
||||
|
||||
|
|
@ -534,7 +593,7 @@ fill_region (db::Cell *cell, const db::Polygon &fp0, db::cell_index_type fill_ce
|
|||
|
||||
// Rasterize to determine fill regions
|
||||
// NOTE: rasterization happens post-shear transformation (e.g. with a rectangular kernel)
|
||||
if ((enhanced_fill && rasterize_extended (*fp, raster_box, am)) || (!enhanced_fill && rasterize_simple (*fp, raster_box, origin, am))) {
|
||||
if ((enhanced_fill && rasterize_extended (fp, raster_box, am)) || (!enhanced_fill && rasterize_simple (fp, raster_box, origin, am))) {
|
||||
|
||||
size_t nx = am.nx ();
|
||||
size_t ny = am.ny ();
|
||||
|
|
@ -585,7 +644,7 @@ fill_region (db::Cell *cell, const db::Polygon &fp0, db::cell_index_type fill_ce
|
|||
}
|
||||
|
||||
if (tl::verbosity () >= 30 && ninsts > 0) {
|
||||
tl::info << "Part " << fp->to_string ();
|
||||
tl::info << "Part " << fpr->to_string ();
|
||||
tl::info << "Created " << ninsts << " instances";
|
||||
}
|
||||
|
||||
|
|
@ -630,7 +689,7 @@ fill_region (db::Cell *cell, const db::Region &fr, db::cell_index_type fill_cell
|
|||
|
||||
static void
|
||||
fill_region_impl (db::Cell *cell, const db::Region &fr, 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,
|
||||
db::Region *remaining_parts, const db::Vector &fill_margin, db::Region *remaining_polygons, int iteration)
|
||||
db::Region *remaining_parts, const db::Vector &fill_margin, db::Region *remaining_polygons, int iteration)
|
||||
{
|
||||
if (row_step.x () <= 0 || column_step.y () <= 0) {
|
||||
throw tl::Exception (tl::to_string (tr ("Invalid row or column step vectors in fill_region: row step must have a positive x component while column step must have a positive y component")));
|
||||
|
|
@ -708,6 +767,7 @@ fill_region_repeat (db::Cell *cell, const db::Region &fr, db::cell_index_type fi
|
|||
|
||||
++iteration;
|
||||
|
||||
remaining.clear ();
|
||||
fill_region_impl (cell, *fill_region, fill_cell_index, kernel_origin, row_step, column_step, db::Point (), true, &remaining, fill_margin, remaining_polygons, iteration);
|
||||
|
||||
new_fill_region.swap (remaining);
|
||||
|
|
|
|||
|
|
@ -213,3 +213,35 @@ TEST(3c)
|
|||
CHECKPOINT();
|
||||
db::compare_layouts (_this, ly, tl::testsrc () + "/testdata/algo/fill_tool_au3c.gds");
|
||||
}
|
||||
|
||||
TEST(4)
|
||||
{
|
||||
db::Layout ly;
|
||||
{
|
||||
std::string fn (tl::testsrc ());
|
||||
fn += "/testdata/algo/fill_tool4.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_polygons;
|
||||
|
||||
db::Vector ko (-100, -130);
|
||||
db::Vector rs (230, 0);
|
||||
db::Vector cs (0, 230);
|
||||
db::fill_region_repeat (&ly.cell (top_cell), fill_region, fill_cell, ko, rs, cs, 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_polygons.insert_into (&ly, top_cell, l101);
|
||||
|
||||
CHECKPOINT();
|
||||
db::compare_layouts (_this, ly, tl::testsrc () + "/testdata/algo/fill_tool_au4.gds");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -176,13 +176,15 @@ FillDialog::generate_fill (const FillParameters &fp)
|
|||
|
||||
const db::Cell *fill_cell = &ly.cell (fc.second);
|
||||
|
||||
std::pair<bool, db::cell_index_type> fc2 = cv->layout ().cell_by_name (fp.fill_cell_name2.c_str ());
|
||||
if (! fc.first) {
|
||||
throw tl::Exception (tl::to_string (QObject::tr ("Secondary fill cell not found: ")) + fp.fill_cell_name2);
|
||||
const db::Cell *fill_cell2 = 0;
|
||||
if (! fp.fill_cell_name2.empty ()) {
|
||||
std::pair<bool, db::cell_index_type> fc2 = cv->layout ().cell_by_name (fp.fill_cell_name2.c_str ());
|
||||
if (! fc2.first) {
|
||||
throw tl::Exception (tl::to_string (QObject::tr ("Secondary fill cell not found: ")) + fp.fill_cell_name2);
|
||||
}
|
||||
fill_cell2 = &ly.cell (fc2.second);
|
||||
}
|
||||
|
||||
const db::Cell *fill_cell2 = &ly.cell (fc2.second);
|
||||
|
||||
db::Vector row_step = db::CplxTrans (ly.dbu ()).inverted () * fp.row_step;
|
||||
db::Vector column_step = db::CplxTrans (ly.dbu ()).inverted () * fp.column_step;
|
||||
db::Vector kernel_origin = db::CplxTrans (ly.dbu ()).inverted () * fp.kernel_origin;
|
||||
|
|
@ -472,7 +474,11 @@ FillDialog::get_fill_parameters ()
|
|||
|
||||
db::DBox fc_bbox = db::CplxTrans (cv->layout ().dbu ()) * (fc_bbox_layer < 0 ? fill_cell->bbox () : fill_cell->bbox (fc_bbox_layer));
|
||||
if (fc_bbox.empty ()) {
|
||||
throw tl::Exception (tl::to_string (QObject::tr ("No valid layer selected to get fill cell's bounding box from - layer is empty for the fill cell")));
|
||||
if (fc_bbox_layer >= 0) {
|
||||
throw tl::Exception (tl::to_string (QObject::tr ("No valid layer selected to get fill cell's bounding box from - layer is empty for the fill cell")));
|
||||
} else {
|
||||
throw tl::Exception (tl::to_string (QObject::tr ("Fill cell is empty")));
|
||||
}
|
||||
}
|
||||
|
||||
s = tl::to_string (row_le->text ());
|
||||
|
|
|
|||
Loading…
Reference in New Issue