mirror of https://github.com/KLayout/klayout.git
Fill cell box introduced as a concept, added tests, overlapping fill cells supported.
This commit is contained in:
parent
74d3251ff7
commit
3f37b0e5a4
|
|
@ -37,13 +37,13 @@ class GenericRasterizer
|
|||
{
|
||||
public:
|
||||
GenericRasterizer ()
|
||||
: m_row_step (), m_column_step (), m_row_steps (0), m_column_steps (0), m_origin ()
|
||||
: m_row_step (), m_column_step (), m_row_steps (0), m_column_steps (0), m_origin (), m_dim ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
GenericRasterizer (const db::Polygon &fp, const db::Vector &row_step, const db::Vector &column_step, const db::Point &origin)
|
||||
: m_row_step (row_step), m_column_step (column_step), m_row_steps (0), m_column_steps (0), m_origin (origin)
|
||||
GenericRasterizer (const db::Polygon &fp, const db::Vector &row_step, const db::Vector &column_step, const db::Point &origin, const db::Vector &dim)
|
||||
: m_row_step (row_step), m_column_step (column_step), m_row_steps (0), m_column_steps (0), m_origin (origin), m_dim (dim)
|
||||
{
|
||||
rasterize (fp);
|
||||
}
|
||||
|
|
@ -76,6 +76,11 @@ public:
|
|||
m_column_steps = tl::lcm (dx, std::abs (m_column_step.x ())) / std::abs (m_column_step.x ());
|
||||
}
|
||||
|
||||
// because the rasterizer can't handle overlapping cells we need to multiply the row and columns steps
|
||||
// with an integer until the effective rasterizer pitch get big enough.
|
||||
m_row_steps *= (m_dim.x () - 1) / (m_row_steps * m_row_step.x ()) + 1;
|
||||
m_column_steps *= (m_dim.y () - 1) / (m_column_steps * m_column_step.y ()) + 1;
|
||||
|
||||
db::Box fp_bbox = fp.box ();
|
||||
|
||||
// compensate for distortion by sheared kernel
|
||||
|
|
@ -115,7 +120,7 @@ public:
|
|||
db::Vector dr = m_row_step * long (ir);
|
||||
db::Vector dc = m_column_step * long (ic);
|
||||
|
||||
am.reinitialize (db::Point (fp_left, fp_bottom) + dr + dc, db::Vector (ddx, ddy), db::Vector (dx, dy), nx, ny);
|
||||
am.reinitialize (db::Point (fp_left, fp_bottom) + dr + dc, db::Vector (ddx, ddy), m_dim, nx, ny);
|
||||
|
||||
if (db::rasterize (fp, am)) {
|
||||
m_area_maps.push_back (db::AreaMap ());
|
||||
|
|
@ -191,11 +196,12 @@ private:
|
|||
db::Vector m_row_step, m_column_step;
|
||||
unsigned int m_row_steps, m_column_steps;
|
||||
db::Point m_origin;
|
||||
db::Vector m_dim;
|
||||
};
|
||||
|
||||
|
||||
static bool
|
||||
fill_polygon_impl (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,
|
||||
fill_polygon_impl (db::Cell *cell, const db::Polygon &fp0, db::cell_index_type fill_cell_index, const db::Box &fc_bbox, 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, const db::Box &glue_box)
|
||||
{
|
||||
if (row_step.x () <= 0 || column_step.y () <= 0) {
|
||||
|
|
@ -211,11 +217,13 @@ fill_polygon_impl (db::Cell *cell, const db::Polygon &fp0, db::cell_index_type f
|
|||
enhanced_fill = false;
|
||||
}
|
||||
|
||||
db::Vector kernel_origin (fc_bbox.left (), fc_bbox.bottom ());
|
||||
|
||||
std::vector <db::Polygon> filled_regions;
|
||||
db::EdgeProcessor ep;
|
||||
|
||||
// under- and oversize the polygon to remove slivers that cannot be filled.
|
||||
db::Coord dx = row_step.x () / 2 - 1, dy = column_step.y () / 2 - 1;
|
||||
db::Coord dx = fc_bbox.width () / 2 - 1, dy = fc_bbox.height () / 2 - 1;
|
||||
|
||||
std::vector <db::Polygon> fpa;
|
||||
std::vector <db::Polygon> fpb;
|
||||
|
|
@ -255,7 +263,7 @@ fill_polygon_impl (db::Cell *cell, const db::Polygon &fp0, db::cell_index_type f
|
|||
o = fp->hull () [0];
|
||||
}
|
||||
|
||||
GenericRasterizer am (*fp, row_step, column_step, o);
|
||||
GenericRasterizer am (*fp, row_step, column_step, o, fc_bbox.p2 () - fc_bbox.p1 ());
|
||||
|
||||
for (unsigned int i = 0; i < am.area_maps (); ++i) {
|
||||
|
||||
|
|
@ -350,10 +358,10 @@ fill_polygon_impl (db::Cell *cell, const db::Polygon &fp0, db::cell_index_type f
|
|||
}
|
||||
|
||||
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,
|
||||
fill_region (db::Cell *cell, const db::Polygon &fp0, db::cell_index_type fill_cell_index, const Box &fc_box, 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, const db::Box &glue_box)
|
||||
{
|
||||
return fill_polygon_impl (cell, fp0, fill_cell_index, kernel_origin, row_step, column_step, origin, enhanced_fill, remaining_parts, fill_margin, glue_box);
|
||||
return fill_polygon_impl (cell, fp0, fill_cell_index, fc_box, row_step, column_step, origin, enhanced_fill, remaining_parts, fill_margin, glue_box);
|
||||
}
|
||||
|
||||
DB_PUBLIC bool
|
||||
|
|
@ -364,11 +372,11 @@ fill_region (db::Cell *cell, const db::Polygon &fp0, db::cell_index_type fill_ce
|
|||
throw tl::Exception (tl::to_string (tr ("Invalid fill cell footprint (empty or zero width/height)")));
|
||||
}
|
||||
|
||||
return fill_polygon_impl (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, glue_box);
|
||||
return fill_polygon_impl (cell, fp0, fill_cell_index, fc_bbox, db::Vector (fc_bbox.width (), 0), db::Vector (0, fc_bbox.height ()), origin, enhanced_fill, remaining_parts, fill_margin, glue_box);
|
||||
}
|
||||
|
||||
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,
|
||||
fill_region_impl (db::Cell *cell, const db::Region &fr, db::cell_index_type fill_cell_index, const db::Box &fc_bbox, 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, const db::Box &glue_box)
|
||||
{
|
||||
if (row_step.x () <= 0 || column_step.y () <= 0) {
|
||||
|
|
@ -396,7 +404,7 @@ fill_region_impl (db::Cell *cell, const db::Region &fr, db::cell_index_type fill
|
|||
tl::RelativeProgress progress (progress_title, n);
|
||||
|
||||
for (db::Region::const_iterator p = fr.begin_merged (); !p.at_end (); ++p) {
|
||||
if (! fill_polygon_impl (cell, *p, fill_cell_index, kernel_origin, row_step, column_step, origin, enhanced_fill, remaining_parts ? &rem_pp : 0, fill_margin, glue_box)) {
|
||||
if (! fill_polygon_impl (cell, *p, fill_cell_index, fc_bbox, row_step, column_step, origin, enhanced_fill, remaining_parts ? &rem_pp : 0, fill_margin, glue_box)) {
|
||||
if (remaining_polygons) {
|
||||
rem_poly.push_back (*p);
|
||||
}
|
||||
|
|
@ -425,10 +433,10 @@ fill_region_impl (db::Cell *cell, const db::Region &fr, db::cell_index_type fill
|
|||
}
|
||||
|
||||
DB_PUBLIC void
|
||||
fill_region (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,
|
||||
fill_region (db::Cell *cell, const db::Region &fr, db::cell_index_type fill_cell_index, const db::Box &fc_bbox, 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, const db::Box &glue_box)
|
||||
{
|
||||
fill_region_impl (cell, fr, fill_cell_index, kernel_origin, row_step, column_step, origin, enhanced_fill, remaining_parts, fill_margin, remaining_polygons, 0, glue_box);
|
||||
fill_region_impl (cell, fr, fill_cell_index, fc_bbox, row_step, column_step, origin, enhanced_fill, remaining_parts, fill_margin, remaining_polygons, 0, glue_box);
|
||||
}
|
||||
|
||||
DB_PUBLIC void
|
||||
|
|
@ -439,13 +447,13 @@ fill_region (db::Cell *cell, const db::Region &fr, db::cell_index_type fill_cell
|
|||
throw tl::Exception (tl::to_string (tr ("Invalid fill cell footprint (empty or zero width/height)")));
|
||||
}
|
||||
|
||||
fill_region_impl (cell, fr, fill_cell_index, fc_bbox.p1 () - db::Point (), db::Vector (fc_bbox.width (), 0), db::Vector (0, fc_bbox.height ()),
|
||||
fill_region_impl (cell, fr, fill_cell_index, fc_bbox, db::Vector (fc_bbox.width (), 0), db::Vector (0, fc_bbox.height ()),
|
||||
origin, enhanced_fill, remaining_parts, fill_margin, remaining_polygons, 0, glue_box);
|
||||
}
|
||||
|
||||
DB_PUBLIC void
|
||||
fill_region_repeat (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::Box &fc_box, const db::Vector &row_step, const db::Vector &column_step,
|
||||
const db::Vector &fill_margin, db::Region *remaining_polygons, const db::Point &origin, const db::Box &glue_box)
|
||||
{
|
||||
const db::Region *fill_region = &fr;
|
||||
|
|
@ -460,7 +468,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, origin, true, &remaining, fill_margin, remaining_polygons, iteration, glue_box);
|
||||
fill_region_impl (cell, *fill_region, fill_cell_index, fc_box, row_step, column_step, origin, true, &remaining, fill_margin, remaining_polygons, iteration, glue_box);
|
||||
|
||||
new_fill_region.swap (remaining);
|
||||
fill_region = &new_fill_region;
|
||||
|
|
|
|||
|
|
@ -50,33 +50,24 @@ class Region;
|
|||
*
|
||||
* Return value: true, if the polygon could be filled, false if no fill tile at all could be applied (remaining_parts will not be fed in that case)
|
||||
*
|
||||
* Explanation for the fill kernel_origin, row step and column step vectors:
|
||||
* Explanation for the fill fc_box, row step and column step vectors:
|
||||
*
|
||||
* The "kernel" is a rectangular or diamond-shaped area which is repeated along it's primary
|
||||
* axes. In case of a box, the kernel is a rectangle and the primary axes are the x and y axes.
|
||||
* The step vectors describe the repetition: in case of the box, the row step vector is (w,0) and
|
||||
* the column step vector is (h,0) (w and h are the box width and heigth respectively). Hence
|
||||
* the kernel will be repeated seamlessly.
|
||||
* The "fc_box" is a rectangular area which is repeated along the primary fill axes given by row_step
|
||||
* and column_step vectors. The fill box is placed with the lower-left corner.
|
||||
*
|
||||
* The kernel's boundary in case of the diamond kernel is:
|
||||
*
|
||||
* (o,o+c,o+c+r,o+r)
|
||||
*
|
||||
* (o = kernel_origin, r = row_step, c = column_step)
|
||||
*
|
||||
* Formally, the kernel will be placed a positions
|
||||
* Formally, the fill box will be placed a positions
|
||||
*
|
||||
* p(i,j) = p0 + i * row_step + j * column_step
|
||||
*
|
||||
* p0 is a position chosen by the fill alogorithm or the "origin", if enhanced_fill is false.
|
||||
*
|
||||
* This pattern is overlaid with the polygon to fill and all instances where the kernel moved by p(i,j) is entirely inside
|
||||
* This pattern is overlaid with the polygon to fill and all instances where the fill box moved by p(i,j) is entirely inside
|
||||
* the polygon generate a fill cell instance with a displacement of p.
|
||||
*
|
||||
* Afterwards, the residual parts are computed by subtracting all moved kernels from the polygon to fill.
|
||||
* Afterwards, the residual parts are computed by subtracting all moved fill boxes from the polygon to fill.
|
||||
* This implies that ideally the fc_boxes should overlap while they are repeated with row_step and column_step.
|
||||
*
|
||||
* As a practical consequence, if all fill cell geometries are within the kernel's boundary, they will also
|
||||
* As a practical consequence, if all fill cell geometries are within the fill boxes boundary, they will also
|
||||
* be within the polygon to fill.
|
||||
*
|
||||
* If the glue box is non-empty, fill cells are guaranteed to use the global origin even in enhanced mode if
|
||||
|
|
@ -92,7 +83,7 @@ fill_region (db::Cell *cell, const db::Polygon &fp, db::cell_index_type fill_cel
|
|||
std::vector <db::Polygon> *remaining_parts = 0, const db::Vector &fill_margin = db::Vector (), const db::Box &glue_box = db::Box ());
|
||||
|
||||
DB_PUBLIC bool
|
||||
fill_region (db::Cell *cell, const db::Polygon &fp, 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,
|
||||
fill_region (db::Cell *cell, const db::Polygon &fp, db::cell_index_type fill_cell_index, const db::Box &fc_box, const db::Vector &row_step, const db::Vector &column_step, const db::Point &origin, bool enhanced_fill,
|
||||
std::vector <db::Polygon> *remaining_parts = 0, const db::Vector &fill_margin = db::Vector (), const db::Box &glue_box = db::Box ());
|
||||
|
||||
|
||||
|
|
@ -111,7 +102,7 @@ fill_region (db::Cell *cell, const db::Region &fr, db::cell_index_type fill_cell
|
|||
db::Region *remaining_parts = 0, const db::Vector &fill_margin = db::Vector (), db::Region *remaining_polygons = 0, const db::Box &glue_box = db::Box ());
|
||||
|
||||
DB_PUBLIC void
|
||||
fill_region (db::Cell *cell, const db::Region &fp, 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,
|
||||
fill_region (db::Cell *cell, const db::Region &fp, db::cell_index_type fill_cell_index, const db::Box &fc_box, const db::Vector &row_step, const db::Vector &column_step, const db::Point &origin, bool enhanced_fill,
|
||||
db::Region *remaining_parts = 0, const db::Vector &fill_margin = db::Vector (), db::Region *remaining_polygons = 0, const db::Box &glue_box = db::Box ());
|
||||
|
||||
/**
|
||||
|
|
@ -126,7 +117,7 @@ fill_region (db::Cell *cell, const db::Region &fp, db::cell_index_type fill_cell
|
|||
*/
|
||||
DB_PUBLIC void
|
||||
fill_region_repeat (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::Box &fc_box, const db::Vector &row_step, const db::Vector &column_step,
|
||||
const db::Vector &fill_margin, db::Region *remaining_polygons = 0, const db::Point &origin = db::Point (), const db::Box &glue_box = db::Box ());
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1304,17 +1304,17 @@ fill_region (db::Cell *cell, const db::Region &fr, db::cell_index_type fill_cell
|
|||
}
|
||||
|
||||
static void
|
||||
fill_region_skew (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,
|
||||
fill_region_skew (db::Cell *cell, const db::Region &fr, db::cell_index_type fill_cell_index, const db::Box &fc_box, const db::Vector &row_step, const db::Vector &column_step, const db::Point *origin,
|
||||
db::Region *remaining_parts, const db::Vector &fill_margin, db::Region *remaining_polygons, const db::Box &glue_box)
|
||||
{
|
||||
db::fill_region (cell, fr, fill_cell_index, kernel_origin, row_step, column_step, origin ? *origin : db::Point (), origin == 0, remaining_parts, fill_margin, remaining_polygons, glue_box);
|
||||
db::fill_region (cell, fr, fill_cell_index, fc_box, row_step, column_step, origin ? *origin : db::Point (), origin == 0, remaining_parts, fill_margin, remaining_polygons, glue_box);
|
||||
}
|
||||
|
||||
static void
|
||||
fill_region_multi (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,
|
||||
fill_region_multi (db::Cell *cell, const db::Region &fr, db::cell_index_type fill_cell_index, const db::Box &fc_box, const db::Vector &row_step, const db::Vector &column_step,
|
||||
const db::Vector &fill_margin, db::Region *remaining_polygons, const db::Point &origin, const db::Box &glue_box)
|
||||
{
|
||||
db::fill_region_repeat (cell, fr, fill_cell_index, kernel_origin, row_step, column_step, fill_margin, remaining_polygons, origin, glue_box);
|
||||
db::fill_region_repeat (cell, fr, fill_cell_index, fc_box, row_step, column_step, fill_margin, remaining_polygons, origin, glue_box);
|
||||
}
|
||||
|
||||
static db::Instance cell_inst_dtransform_simple (db::Cell *cell, const db::Instance &inst, const db::DTrans &t)
|
||||
|
|
@ -1846,7 +1846,7 @@ Class<db::Cell> decl_Cell ("db", "Cell",
|
|||
) +
|
||||
gsi::method_ext ("fill_region", &fill_region_skew, gsi::arg ("region"),
|
||||
gsi::arg ("fill_cell_index"),
|
||||
gsi::arg ("fc_origin"),
|
||||
gsi::arg ("fc_bbox"),
|
||||
gsi::arg ("row_step"),
|
||||
gsi::arg ("column_step"),
|
||||
gsi::arg ("origin", &default_origin, "(0, 0)"),
|
||||
|
|
@ -1857,7 +1857,7 @@ Class<db::Cell> decl_Cell ("db", "Cell",
|
|||
"@brief Fills the given region with cells of the given type (skew step version)\n"
|
||||
"@param region The region to fill\n"
|
||||
"@param fill_cell_index The fill cell to place\n"
|
||||
"@param fc_origin The location of the reference point of the fill cell\n"
|
||||
"@param fc_bbox The fill cell's box to place\n"
|
||||
"@param row_step The 'rows' step vector\n"
|
||||
"@param column_step The 'columns' step vector\n"
|
||||
"@param origin The global origin of the fill pattern or nil to allow local (per-polygon) optimization\n"
|
||||
|
|
@ -1865,14 +1865,18 @@ Class<db::Cell> decl_Cell ("db", "Cell",
|
|||
"@param fill_margin See explanation in other version\n"
|
||||
"@param remaining_polygons See explanation in other version\n"
|
||||
"\n"
|
||||
"This version is similar to the version providing a rectangular fill kernel, but it offers more generic stepping of the fill cell.\n"
|
||||
"This version is similar to the version providing an orthogonal fill, but it offers more generic stepping of the fill cell.\n"
|
||||
"The step pattern is defined by an origin and two vectors (row_step and column_step) which span the axes of the fill cell pattern.\n"
|
||||
"\n"
|
||||
"The fill box and the step vectors are decoupled which means the fill box can be larger or smaller than the step pitch - it can "
|
||||
"be overlapping and there can be space between the fill box instances. Fill boxes are placed where they fit entirely into a polygon of the region. "
|
||||
"The fill boxes lower left corner is the reference for the fill pattern and aligns with the origin if given.\n"
|
||||
"\n"
|
||||
"This variant has been introduced in version 0.27.\n"
|
||||
) +
|
||||
gsi::method_ext ("fill_region_multi", &fill_region_multi, gsi::arg ("region"),
|
||||
gsi::arg ("fill_cell_index"),
|
||||
gsi::arg ("fc_origin"),
|
||||
gsi::arg ("fc_bbox"),
|
||||
gsi::arg ("row_step"),
|
||||
gsi::arg ("column_step"),
|
||||
gsi::arg ("fill_margin", db::Vector ()),
|
||||
|
|
|
|||
|
|
@ -722,17 +722,17 @@ fill_region (const db::Region *fr, db::Cell *cell, db::cell_index_type fill_cell
|
|||
}
|
||||
|
||||
static void
|
||||
fill_region_skew (const db::Region *fr, db::Cell *cell, 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,
|
||||
fill_region_skew (const db::Region *fr, db::Cell *cell, db::cell_index_type fill_cell_index, const db::Box &fc_box, const db::Vector &row_step, const db::Vector &column_step, const db::Point *origin,
|
||||
db::Region *remaining_parts, const db::Vector &fill_margin, db::Region *remaining_polygons, const db::Box &glue_box)
|
||||
{
|
||||
db::fill_region (cell, *fr, fill_cell_index, kernel_origin, row_step, column_step, origin ? *origin : db::Point (), origin == 0, remaining_parts, fill_margin, remaining_polygons, glue_box);
|
||||
db::fill_region (cell, *fr, fill_cell_index, fc_box, row_step, column_step, origin ? *origin : db::Point (), origin == 0, remaining_parts, fill_margin, remaining_polygons, glue_box);
|
||||
}
|
||||
|
||||
static void
|
||||
fill_region_multi (const db::Region *fr, db::Cell *cell, db::cell_index_type fill_cell_index, const db::Vector &kernel_origin, const db::Vector &row_step, const db::Vector &column_step,
|
||||
fill_region_multi (const db::Region *fr, db::Cell *cell, db::cell_index_type fill_cell_index, const db::Box &fc_box, const db::Vector &row_step, const db::Vector &column_step,
|
||||
const db::Vector &fill_margin, db::Region *remaining_polygons, const db::Point &origin, const db::Box &glue_box)
|
||||
{
|
||||
db::fill_region_repeat (cell, *fr, fill_cell_index, kernel_origin, row_step, column_step, fill_margin, remaining_polygons, origin, glue_box);
|
||||
db::fill_region_repeat (cell, *fr, fill_cell_index, fc_box, row_step, column_step, fill_margin, remaining_polygons, origin, glue_box);
|
||||
}
|
||||
|
||||
static db::Point default_origin;
|
||||
|
|
|
|||
|
|
@ -104,7 +104,8 @@ TEST(3)
|
|||
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);
|
||||
db::Box fc_box (db::Point () + ko, db::Point (rs.x (), cs.y ()) + ko);
|
||||
db::fill_region (&ly.cell (top_cell), fill_region, fill_cell, fc_box, 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));
|
||||
|
|
@ -137,7 +138,8 @@ TEST(3a)
|
|||
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);
|
||||
db::Box fc_box (db::Point () + ko, db::Point (rs.x (), cs.y ()) + ko);
|
||||
db::fill_region (&ly.cell (top_cell), fill_region, fill_cell, fc_box, 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));
|
||||
|
|
@ -170,7 +172,8 @@ TEST(3b)
|
|||
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);
|
||||
db::Box fc_box (db::Point () + ko, db::Point (rs.x (), cs.y ()) + ko);
|
||||
db::fill_region (&ly.cell (top_cell), fill_region, fill_cell, fc_box, 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));
|
||||
|
|
@ -203,7 +206,8 @@ TEST(3c)
|
|||
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);
|
||||
db::Box fc_box (db::Point () + ko, db::Point (rs.x (), cs.y ()) + ko);
|
||||
db::fill_region (&ly.cell (top_cell), fill_region, fill_cell, fc_box, 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));
|
||||
|
|
@ -236,12 +240,76 @@ TEST(4)
|
|||
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);
|
||||
db::Box fc_box (db::Point () + ko, db::Point (rs.x (), cs.y ()) + ko);
|
||||
db::fill_region_repeat (&ly.cell (top_cell), fill_region, fill_cell, fc_box, 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");
|
||||
}
|
||||
|
||||
TEST(4b)
|
||||
{
|
||||
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::Box fc_box (db::Point () + ko, db::Point ());
|
||||
db::fill_region (&ly.cell (top_cell), fill_region, fill_cell, fc_box, rs, cs, db::Point (), true, &remaining_polygons);
|
||||
|
||||
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_au4b.gds");
|
||||
}
|
||||
|
||||
TEST(4c)
|
||||
{
|
||||
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::Box fc_box (db::Point () + ko, db::Point (rs.x (), cs.y ()) + ko);
|
||||
db::fill_region (&ly.cell (top_cell), fill_region, fill_cell, fc_box.enlarged (db::Vector (100, 100)), rs, cs, db::Point (), true, &remaining_polygons);
|
||||
|
||||
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_au4c.gds");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -187,11 +187,11 @@ FillDialog::generate_fill (const FillParameters &fp)
|
|||
|
||||
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;
|
||||
db::Box fc_bbox = db::CplxTrans (ly.dbu ()).inverted () * fp.fc_bbox;
|
||||
|
||||
db::Vector row_step2 = db::CplxTrans (ly.dbu ()).inverted () * fp.row_step2;
|
||||
db::Vector column_step2 = db::CplxTrans (ly.dbu ()).inverted () * fp.column_step2;
|
||||
db::Vector kernel_origin2 = db::CplxTrans (ly.dbu ()).inverted () * fp.kernel_origin2;
|
||||
db::Box fc_bbox2 = db::CplxTrans (ly.dbu ()).inverted () * fp.fc_bbox2;
|
||||
|
||||
|
||||
if (tl::verbosity () >= 20) {
|
||||
|
|
@ -271,15 +271,15 @@ FillDialog::generate_fill (const FillParameters &fp)
|
|||
}
|
||||
|
||||
if (! enhanced_fill) {
|
||||
db::fill_region (cv.cell (), fill_region, fill_cell->cell_index (), kernel_origin, row_step, column_step, fr_bbox.p1 (), false, fill_cell2 ? &fill_region : 0, fill_margin, fill_cell2 ? &fill_region : 0);
|
||||
db::fill_region (cv.cell (), fill_region, fill_cell->cell_index (), fc_bbox, row_step, column_step, fr_bbox.p1 (), false, fill_cell2 ? &fill_region : 0, fill_margin, fill_cell2 ? &fill_region : 0);
|
||||
} else {
|
||||
db::fill_region_repeat (cv.cell (), fill_region, fill_cell->cell_index (), kernel_origin, row_step, column_step, fill_margin, fill_cell2 ? &fill_region : 0);
|
||||
db::fill_region_repeat (cv.cell (), fill_region, fill_cell->cell_index (), fc_bbox, row_step, column_step, fill_margin, fill_cell2 ? &fill_region : 0);
|
||||
}
|
||||
|
||||
fill_cell = fill_cell2;
|
||||
row_step = row_step2;
|
||||
column_step = column_step2;
|
||||
kernel_origin = kernel_origin2;
|
||||
fc_bbox = fc_bbox2;
|
||||
fill_margin = fill_margin2;
|
||||
|
||||
fill_cell2 = 0;
|
||||
|
|
@ -497,13 +497,12 @@ FillDialog::get_fill_parameters ()
|
|||
fp.column_step = db::DVector (0.0, fc_bbox.height ());
|
||||
}
|
||||
|
||||
fp.kernel_origin = fc_bbox.p1 () - db::DPoint ();
|
||||
|
||||
const db::Cell *fill_cell2 = 0;
|
||||
db::DBox fc_bbox2;
|
||||
fp.fc_bbox = fc_bbox;
|
||||
|
||||
if (second_order_fill_cb->isChecked ()) {
|
||||
|
||||
db::DBox fc_bbox2;
|
||||
|
||||
fp.fill_cell_name2 = tl::to_string (fill_cell_2nd_le->text ());
|
||||
|
||||
std::pair<bool, db::cell_index_type> fc = cv->layout ().cell_by_name (fp.fill_cell_name2.c_str ());
|
||||
|
|
@ -511,7 +510,7 @@ FillDialog::get_fill_parameters ()
|
|||
throw tl::Exception (tl::to_string (QObject::tr ("Second order fill cell not found: ")) + tl::to_string (fill_cell_2nd_le->text ()));
|
||||
}
|
||||
|
||||
fill_cell2 = &cv->layout ().cell (fc.second);
|
||||
const db::Cell *fill_cell2 = &cv->layout ().cell (fc.second);
|
||||
|
||||
fc_bbox2 = db::CplxTrans (cv->layout ().dbu ()) * (fc_bbox_layer < 0 ? fill_cell2->bbox () : fill_cell2->bbox (fc_bbox_layer));
|
||||
if (fc_bbox2.empty ()) {
|
||||
|
|
@ -534,6 +533,8 @@ FillDialog::get_fill_parameters ()
|
|||
fp.column_step2 = db::DVector (0.0, fc_bbox2.height ());
|
||||
}
|
||||
|
||||
fp.fc_bbox2 = fc_bbox2;
|
||||
|
||||
}
|
||||
|
||||
return fp;
|
||||
|
|
|
|||
|
|
@ -60,10 +60,12 @@ struct LAY_PUBLIC FillParameters
|
|||
bool enhanced_fill;
|
||||
std::string fill_cell_name;
|
||||
db::DVector fill_cell_margin;
|
||||
db::DVector kernel_origin, row_step, column_step;
|
||||
db::DVector row_step, column_step;
|
||||
db::DBox fc_bbox;
|
||||
std::string fill_cell_name2;
|
||||
db::DVector fill_cell_margin2;
|
||||
db::DVector kernel_origin2, row_step2, column_step2;
|
||||
db::DVector row_step2, column_step2;
|
||||
db::DBox fc_bbox2;
|
||||
};
|
||||
|
||||
class LAY_PUBLIC FillDialog
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue