mirror of https://github.com/KLayout/klayout.git
DRC support for fill, experimental
This commit is contained in:
parent
94ffc0483e
commit
76982a3206
|
|
@ -101,6 +101,11 @@ struct box_defs
|
|||
return std::hfunc (*box);
|
||||
}
|
||||
|
||||
static const C &bbox (const C *box)
|
||||
{
|
||||
return *box;
|
||||
}
|
||||
|
||||
static gsi::Methods methods ()
|
||||
{
|
||||
return
|
||||
|
|
@ -172,6 +177,12 @@ struct box_defs
|
|||
method ("p2=", &C::set_p2, gsi::arg ("p"),
|
||||
"@brief Sets the upper right point of the box\n"
|
||||
) +
|
||||
method_ext ("bbox", &bbox,
|
||||
"@brief Returns the bounding box\n"
|
||||
"This method is provided for consistency of the shape API is returns the box itself.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.27."
|
||||
) +
|
||||
method_ext ("contains?", &box_defs<C>::contains, gsi::arg ("x"), gsi::arg ("y"),
|
||||
"@brief Returns true if the box contains the given point\n"
|
||||
"\n"
|
||||
|
|
|
|||
|
|
@ -1298,21 +1298,21 @@ static void move_tree_shapes3 (db::Cell *cell, db::Cell &source_cell, const db::
|
|||
|
||||
static void
|
||||
fill_region (db::Cell *cell, const db::Region &fr, db::cell_index_type fill_cell_index, const db::Box &fc_box, const db::Point *origin,
|
||||
db::Region *remaining_parts, const db::Vector &fill_margin, db::Region *remaining_polygons, const db::Box &glue_box)
|
||||
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, fc_box, origin ? *origin : db::Point (), origin == 0 || !glue_box.empty (), remaining_parts, fill_margin, remaining_polygons, glue_box);
|
||||
db::fill_region (cell, fr, fill_cell_index, fc_box, origin ? *origin : db::Point (), origin == 0, remaining_parts, fill_margin, remaining_polygons, glue_box);
|
||||
}
|
||||
|
||||
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,
|
||||
db::Region *remaining_parts, const db::Vector &fill_margin, db::Region *remaining_polygons, const db::Box &glue_box)
|
||||
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 || !glue_box.empty (), remaining_parts, fill_margin, remaining_polygons, 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);
|
||||
}
|
||||
|
||||
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,
|
||||
const db::Vector &fill_margin, db::Region *remaining_polygons, const db::Point &origin, const db::Box &glue_box)
|
||||
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);
|
||||
}
|
||||
|
|
@ -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 ("kernel_origin"),
|
||||
gsi::arg ("fc_origin"),
|
||||
gsi::arg ("row_step"),
|
||||
gsi::arg ("column_step"),
|
||||
gsi::arg ("origin", &default_origin, "(0, 0)"),
|
||||
|
|
@ -1857,23 +1857,22 @@ 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 kernel_origin The fill cell's footprint\n"
|
||||
"@param row_step The fill cell's footprint\n"
|
||||
"@param column_step The fill cell's footprint\n"
|
||||
"@param fc_origin The location of the reference point of the fill cell\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"
|
||||
"@param remaining_parts See explanation in other version\n"
|
||||
"@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 a more generic, diamond-shaped kernel.\n"
|
||||
"The kerne is defined by an origin and two vectors (row_step and column_step) which span the diamond.\n"
|
||||
"This version will try to fit as many of these diamond-shaped kernels into the region to fill.\n"
|
||||
"This version is similar to the version providing a rectangular fill kernel, 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"
|
||||
"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 ("kernel_origin"),
|
||||
gsi::arg ("fc_origin"),
|
||||
gsi::arg ("row_step"),
|
||||
gsi::arg ("column_step"),
|
||||
gsi::arg ("fill_margin", db::Vector ()),
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#include "dbShapes.h"
|
||||
#include "dbDeepShapeStore.h"
|
||||
#include "dbRegion.h"
|
||||
#include "dbFillTool.h"
|
||||
#include "dbRegionProcessors.h"
|
||||
#include "dbCompoundOperation.h"
|
||||
#include "tlGlobPattern.h"
|
||||
|
|
@ -675,6 +676,29 @@ tl::Variant complex_op (db::Region *region, db::CompoundRegionOperationNode *nod
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
fill_region (const db::Region *fr, db::Cell *cell, db::cell_index_type fill_cell_index, const db::Box &fc_box, 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, fc_box, origin ? *origin : db::Point (), origin == 0, remaining_parts, fill_margin, remaining_polygons, glue_box);
|
||||
}
|
||||
|
||||
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,
|
||||
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);
|
||||
}
|
||||
|
||||
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,
|
||||
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);
|
||||
}
|
||||
|
||||
static db::Point default_origin;
|
||||
|
||||
// provided by gsiDeclDbPolygon.cc:
|
||||
int td_simple ();
|
||||
int po_any ();
|
||||
|
|
@ -2748,6 +2772,51 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
"See \\base_verbosity= for details.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.26.\n"
|
||||
) +
|
||||
gsi::method_ext ("fill", &fill_region, gsi::arg ("in_cell"),
|
||||
gsi::arg ("fill_cell_index"),
|
||||
gsi::arg ("fc_box"),
|
||||
gsi::arg ("origin", &default_origin, "(0, 0)"),
|
||||
gsi::arg ("remaining_parts", (db::Region *)0, "nil"),
|
||||
gsi::arg ("fill_margin", db::Vector ()),
|
||||
gsi::arg ("remaining_polygons", (db::Region *)0, "nil"),
|
||||
gsi::arg ("glue_box", db::Box ()),
|
||||
"@brief A mapping of \\Cell#fill_region to the Region class\n"
|
||||
"\n"
|
||||
"This method is equivalent to \\Cell#fill_region, but is based on Region (with the cell being the first parameter).\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.27.\n"
|
||||
) +
|
||||
gsi::method_ext ("fill", &fill_region_skew, gsi::arg ("in_cell"),
|
||||
gsi::arg ("fill_cell_index"),
|
||||
gsi::arg ("fc_origin"),
|
||||
gsi::arg ("row_step"),
|
||||
gsi::arg ("column_step"),
|
||||
gsi::arg ("origin", &default_origin, "(0, 0)"),
|
||||
gsi::arg ("remaining_parts", (db::Region *)0, "nil"),
|
||||
gsi::arg ("fill_margin", db::Vector ()),
|
||||
gsi::arg ("remaining_polygons", (db::Region *)0, "nil"),
|
||||
gsi::arg ("glue_box", db::Box ()),
|
||||
"@brief A mapping of \\Cell#fill_region to the Region class\n"
|
||||
"\n"
|
||||
"This method is equivalent to \\Cell#fill_region, but is based on Region (with the cell being the first parameter).\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.27.\n"
|
||||
) +
|
||||
gsi::method_ext ("fill_multi", &fill_region_multi, gsi::arg ("in_cell"),
|
||||
gsi::arg ("fill_cell_index"),
|
||||
gsi::arg ("fc_origin"),
|
||||
gsi::arg ("row_step"),
|
||||
gsi::arg ("column_step"),
|
||||
gsi::arg ("fill_margin", db::Vector ()),
|
||||
gsi::arg ("remaining_polygons", (db::Region *)0, "nil"),
|
||||
gsi::arg ("origin", db::Point ()),
|
||||
gsi::arg ("glue_box", db::Box ()),
|
||||
"@brief A mapping of \\Cell#fill_region to the Region class\n"
|
||||
"\n"
|
||||
"This method is equivalent to \\Cell#fill_region, but is based on Region (with the cell being the first parameter).\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.27.\n"
|
||||
),
|
||||
"@brief A region (a potentially complex area consisting of multiple polygons)\n"
|
||||
"\n\n"
|
||||
|
|
|
|||
|
|
@ -211,16 +211,16 @@ module DRC
|
|||
end
|
||||
end
|
||||
|
||||
def fill_cell(name)
|
||||
def fill_pattern(name)
|
||||
DRCFillCell::new(name)
|
||||
end
|
||||
|
||||
def hstep(x, y = nil)
|
||||
DRCFillStep(true, x, y)
|
||||
DRCFillStep::new(true, x, y)
|
||||
end
|
||||
|
||||
def vstep(x, y = nil)
|
||||
DRCFillStep(false, x, y)
|
||||
DRCFillStep::new(false, x, y)
|
||||
end
|
||||
|
||||
def auto_origin
|
||||
|
|
@ -1967,7 +1967,7 @@ CODE
|
|||
end
|
||||
|
||||
# disable progress again
|
||||
if obj.is_a?(RBA::Region)
|
||||
if obj.is_a?(RBA::Region) || obj.is_a?(RBA::Edges) || obj.is_a?(RBA::EdgePairs) || obj.is_a?(RBA::Texts)
|
||||
obj.disable_progress
|
||||
end
|
||||
|
||||
|
|
@ -2022,7 +2022,7 @@ CODE
|
|||
end
|
||||
|
||||
# disable progress again
|
||||
if obj.is_a?(RBA::Region)
|
||||
if obj.is_a?(RBA::Region) || obj.is_a?(RBA::Edges) || obj.is_a?(RBA::EdgePairs) || obj.is_a?(RBA::Texts)
|
||||
obj.disable_progress
|
||||
end
|
||||
|
||||
|
|
@ -2065,7 +2065,7 @@ CODE
|
|||
end
|
||||
|
||||
# disable progress again
|
||||
if obj.is_a?(RBA::Region)
|
||||
if obj.is_a?(RBA::Region) || obj.is_a?(RBA::Edges) || obj.is_a?(RBA::EdgePairs) || obj.is_a?(RBA::Texts)
|
||||
obj.disable_progress
|
||||
end
|
||||
|
||||
|
|
@ -2084,6 +2084,22 @@ CODE
|
|||
obj.send(method, *args)
|
||||
end
|
||||
end
|
||||
|
||||
def _bx
|
||||
@bx
|
||||
end
|
||||
|
||||
def _by
|
||||
@by
|
||||
end
|
||||
|
||||
def _tx
|
||||
@tx
|
||||
end
|
||||
|
||||
def _ty
|
||||
@ty
|
||||
end
|
||||
|
||||
def _start
|
||||
|
||||
|
|
|
|||
|
|
@ -3898,6 +3898,9 @@ CODE
|
|||
|
||||
def fill(*args)
|
||||
|
||||
# generation of new cells not tested in deep mode
|
||||
@deep && raise("fill command not supported in deep mode currently")
|
||||
|
||||
m = "fill"
|
||||
|
||||
source = @engine.source
|
||||
|
|
@ -3922,12 +3925,12 @@ CODE
|
|||
if row_step
|
||||
raise("Duplicate hstep specification for '#{m}' at argument ##{ai+1}")
|
||||
end
|
||||
row_step = a
|
||||
row_step = a.step
|
||||
else
|
||||
if column_step
|
||||
raise("Duplicate vstep specification for '#{m}' at argument ##{ai+1}")
|
||||
end
|
||||
column_step = a
|
||||
column_step = a.step
|
||||
end
|
||||
elsif a.is_a?(DRCFillOrigin)
|
||||
origin = a.origin
|
||||
|
|
@ -3937,7 +3940,7 @@ CODE
|
|||
end
|
||||
|
||||
if !pattern
|
||||
raise("No fill pattern given for '#{m}'")
|
||||
raise("No fill pattern given for '#{m}' (use 'fill_pattern')")
|
||||
end
|
||||
|
||||
if !row_step
|
||||
|
|
@ -3947,7 +3950,64 @@ CODE
|
|||
column_step = RBA::DVector::new(0, pattern.bbox.height)
|
||||
end
|
||||
|
||||
dbu_trans = RBA::VCplxTrans::new(1.0 / @engine.dbu)
|
||||
|
||||
fill_cell = pattern.create_cell(source.layout)
|
||||
top_cell = source.cell_obj
|
||||
ko = dbu_trans * pattern.cell_origin
|
||||
rs = dbu_trans * row_step
|
||||
cs = dbu_trans * column_step
|
||||
origin = origin ? dbu_trans * origin : nil
|
||||
fc_index = fill_cell.cell_index
|
||||
|
||||
if @engine._tx && @engine._ty
|
||||
|
||||
tp = RBA::TilingProcessor::new
|
||||
tp.dbu = @engine.dbu
|
||||
tp.scale_to_dbu = false
|
||||
tp.tile_size(@engine._tx, @engine._ty)
|
||||
bx = [ @engine._bx || 0.0, row_step.x ].max
|
||||
by = [ @engine._by || 0.0, column_step.y ].max
|
||||
tp.tile_border(bx, by)
|
||||
tp.threads = (@engine.threads || 1)
|
||||
|
||||
tp.input("region", self.data)
|
||||
tp.var("top_cell", top_cell)
|
||||
tp.var("ko", ko)
|
||||
tp.var("rs", rs)
|
||||
tp.var("cs", cs)
|
||||
tp.var("origin", origin)
|
||||
tp.var("fc_index", fc_index)
|
||||
|
||||
tp.queue(<<"END")
|
||||
var tc_box = top_cell.bbox;
|
||||
var tile_box = _tile ? (tc_box & _tile.bbox) : top_cell.bbox;
|
||||
!tile_box.empty && (
|
||||
tile_box.right = tile_box.right + rs.x - 1;
|
||||
tile_box.top = tile_box.top + cs.y - 1;
|
||||
tile_box = tile_box & tc_box;
|
||||
(region & tile_box).fill(top_cell, fc_index, ko, rs, cs, origin, nil, Vector.new, nil, _tile.bbox)
|
||||
)
|
||||
END
|
||||
|
||||
begin
|
||||
source.layout.start_changes
|
||||
@engine.run_timed("\"#{m}\" in: #{@engine.src_line}", self.data) do
|
||||
tp.execute("Tiled \"#{m}\" in: #{@engine.src_line}")
|
||||
end
|
||||
ensure
|
||||
source.layout.end_changes
|
||||
end
|
||||
|
||||
else
|
||||
|
||||
@engine.run_timed("\"#{m}\" in: #{@engine.src_line}", self.data) do
|
||||
self.data.fill(top_cell, fc_index, ko, rs, cs, origin)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
self.data.disable_progress
|
||||
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -190,6 +190,27 @@ module DRC
|
|||
@origin = RBA::DVector::new
|
||||
end
|
||||
|
||||
def create_cell(layout)
|
||||
cell = layout.create_cell(@cell_name)
|
||||
@shapes.each do |s|
|
||||
li = layout.layer(s[0])
|
||||
s[1].each { |t| cell.shapes(li).insert(t) }
|
||||
end
|
||||
cell
|
||||
end
|
||||
|
||||
def cell_origin
|
||||
@origin
|
||||
end
|
||||
|
||||
def bbox
|
||||
box = RBA::DBox::new
|
||||
@shapes.each do |s|
|
||||
s[1].each { |t| box += t.bbox }
|
||||
end
|
||||
box
|
||||
end
|
||||
|
||||
def shape(*args)
|
||||
|
||||
layer = nil
|
||||
|
|
@ -201,7 +222,6 @@ module DRC
|
|||
if a.is_a?(1.class)
|
||||
if !layer
|
||||
layer = a
|
||||
datatype = 0
|
||||
elsif !datatype
|
||||
datatype = a
|
||||
else
|
||||
|
|
@ -223,17 +243,24 @@ module DRC
|
|||
if !shapes.empty?
|
||||
|
||||
li = RBA::LayerInfo::new
|
||||
layer && li.layer = layer
|
||||
datatype && li.datatype = datatype
|
||||
name && li.name = name
|
||||
if layer
|
||||
li.layer = layer
|
||||
li.datatype = datatype || 0
|
||||
end
|
||||
if name
|
||||
li.name = name
|
||||
end
|
||||
|
||||
@shapes << [ li, shapes ]
|
||||
|
||||
end
|
||||
|
||||
self
|
||||
|
||||
end
|
||||
|
||||
def origin(x, y)
|
||||
|
||||
if !x.is_a?(1.class) && !x.is_a?(1.0.class)
|
||||
raise("x argument not numeric FillCell#origin")
|
||||
end
|
||||
|
|
@ -241,6 +268,9 @@ module DRC
|
|||
raise("y argument not numeric FillCell#origin")
|
||||
end
|
||||
@origin = RBA::DVector::new(x, y)
|
||||
|
||||
self
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
Loading…
Reference in New Issue