mirror of https://github.com/KLayout/klayout.git
FEATURE: 'labels' method in DRC scripts allows copying labels to output layers.
This commit is contained in:
parent
86aea962c9
commit
ccfe6fa918
|
|
@ -1,5 +1,8 @@
|
|||
0.25.3
|
||||
|
||||
* Enhancement: Pass label (text) layers through DRC script
|
||||
The "labels" method now allows copying labels from a layer
|
||||
to the output.
|
||||
* Enhancement: New "split" method for polygons
|
||||
This method will fragment the polygons into two or more
|
||||
smaller parts for reducing their vertex count.
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
def run_demo(gen, cmd, out)
|
||||
|
||||
img_path = "src/lay/doc/images"
|
||||
img_path = "src/lay/lay/doc/images"
|
||||
|
||||
mw = RBA::Application::instance::main_window
|
||||
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@
|
|||
$script_call = $0 + " " + ARGV.join(" ")
|
||||
|
||||
$key="%DRC%"
|
||||
$infile="src/lay/built_in_macros/drc.lym"
|
||||
$infile="src/drc/drc/built-in-macros/drc.lym"
|
||||
$loc = "about/drc_ref"
|
||||
$outfiles="src/lay/doc"
|
||||
$outfiles="src/lay/lay/doc"
|
||||
$title="DRC Reference"
|
||||
|
||||
def create_ref(s)
|
||||
|
|
|
|||
|
|
@ -3469,7 +3469,68 @@ CODE
|
|||
# @/ul
|
||||
|
||||
def input(*args)
|
||||
layers = parse_input_layers(*args)
|
||||
DRCLayer::new(@engine, @engine._cmd(@engine, :_input, @layout_var, @cell.cell_index, layers, @sel, @box, @clip, @overlapping, false))
|
||||
end
|
||||
|
||||
# %DRC%
|
||||
# @name labels
|
||||
# @brief Gets the labels (texts) from an input layer
|
||||
# @synopsis source.labels(layer)
|
||||
# @synopsis source.labels(layer, datatype)
|
||||
# @synopsis source.labels(layer_into)
|
||||
# @synopsis source.labels(filter, ...)
|
||||
# Creates a layer with the labels from the given layer of the source.
|
||||
# The layer can be specified by layer and optionally datatype, by a RBA::LayerInfo
|
||||
# object or by a sequence of filters.
|
||||
# Filters are expressions describing ranges
|
||||
# of layers and/or datatype numbers or layer names. Multiple filters
|
||||
# can be given and all layers matching at least one of these filter
|
||||
# expressions are joined to render the label collection. See "input" for
|
||||
# more details about the input layer specification.
|
||||
#
|
||||
# Label layers currently can only be passed to an output layer.
|
||||
# Processing of labels is not supported. See "texts" for a way to filter
|
||||
# texts and use the text locations in geometrical operations.
|
||||
#
|
||||
# @code
|
||||
# labels(1, 0).output(100, 0)
|
||||
# @/code
|
||||
|
||||
def labels(*args)
|
||||
layers = parse_input_layers(*args)
|
||||
DRCLayer::new(@engine, @engine._cmd(@engine, :_input, @layout_var, @cell.cell_index, layers, @sel, @box, @clip, @overlapping, true))
|
||||
end
|
||||
|
||||
# %DRC%
|
||||
# @name layers
|
||||
# @brief Gets the layers the source contains
|
||||
# @synopsis source.layers
|
||||
# Delivers a list of RBA::LayerInfo objects representing the layers
|
||||
# inside the source.
|
||||
#
|
||||
# One application is to read all layers from a source. In the following
|
||||
# example, the "and" operation is used to perform a clip with the given
|
||||
# rectangle. Note that this solution is not efficient - it's provided
|
||||
# as an example only:
|
||||
#
|
||||
# @code
|
||||
# output_cell("Clipped")
|
||||
#
|
||||
# clip_box = polygon_layer
|
||||
# clip_box.insert(box(0.um, -4.um, 4.um, 0.um))
|
||||
#
|
||||
# layers.each { |l| (input(l) & clip_box).output(l) }
|
||||
# @/code
|
||||
|
||||
def layers
|
||||
@layout.layer_indices.collect { |li| @layout.get_info(li) }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def parse_input_layers(*args)
|
||||
|
||||
layers = []
|
||||
|
||||
if args.size == 0
|
||||
|
|
@ -3504,36 +3565,11 @@ CODE
|
|||
end
|
||||
|
||||
end
|
||||
|
||||
DRCLayer::new(@engine, @engine._cmd(@engine, :_input, @layout_var, @cell.cell_index, layers, @sel, @box, @clip, @overlapping))
|
||||
|
||||
layers
|
||||
|
||||
end
|
||||
|
||||
# %DRC%
|
||||
# @name layers
|
||||
# @brief Gets the layers the source contains
|
||||
# @synopsis source.layers
|
||||
# Delivers a list of RBA::LayerInfo objects representing the layers
|
||||
# inside the source.
|
||||
#
|
||||
# One application is to read all layers from a source. In the following
|
||||
# example, the "and" operation is used to perform a clip with the given
|
||||
# rectangle. Note that this solution is not efficient - it's provided
|
||||
# as an example only:
|
||||
#
|
||||
# @code
|
||||
# output_cell("Clipped")
|
||||
#
|
||||
# clip_box = polygon_layer
|
||||
# clip_box.insert(box(0.um, -4.um, 4.um, 0.um))
|
||||
#
|
||||
# layers.each { |l| (input(l) & clip_box).output(l) }
|
||||
# @/code
|
||||
|
||||
def layers
|
||||
@layout.layer_indices.collect { |li| @layout.get_info(li) }
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# The DRC engine
|
||||
|
|
@ -4283,6 +4319,16 @@ CODE
|
|||
layout.input(*args)
|
||||
end
|
||||
|
||||
# %DRC%
|
||||
# @name labels
|
||||
# @brief Gets the labels (text) from an original layer
|
||||
# @synopsis labels
|
||||
# See \Source#labels for a description of that function.
|
||||
|
||||
def labels(*args)
|
||||
layout.labels(*args)
|
||||
end
|
||||
|
||||
# %DRC%
|
||||
# @name output
|
||||
# @brief Outputs a layer to the report database or output layout
|
||||
|
|
@ -4630,7 +4676,7 @@ CODE
|
|||
end
|
||||
end
|
||||
|
||||
def _input(layout, cell_index, layers, sel, box, clip, overlapping)
|
||||
def _input(layout, cell_index, layers, sel, box, clip, overlapping, labels_only)
|
||||
|
||||
if layers.empty?
|
||||
r = RBA::Region::new
|
||||
|
|
@ -4641,6 +4687,9 @@ CODE
|
|||
else
|
||||
iter = RBA::RecursiveShapeIterator::new(layout, layout.cell(cell_index), layers)
|
||||
end
|
||||
if labels_only
|
||||
iter.shape_flags = RBA::Shapes::STexts
|
||||
end
|
||||
|
||||
sel.each do |s|
|
||||
if s == "-"
|
||||
|
|
@ -4657,17 +4706,26 @@ CODE
|
|||
iter.select_cells(s)
|
||||
end
|
||||
end
|
||||
|
||||
sf = layout.dbu / self.dbu
|
||||
if (sf - 1.0).abs > 1e-6
|
||||
r = RBA::Region::new(iter, RBA::ICplxTrans::new(sf.to_f))
|
||||
|
||||
if labels_only
|
||||
|
||||
# for labels layers, the iterator is the data (no region)
|
||||
r = iter
|
||||
|
||||
else
|
||||
r = RBA::Region::new(iter)
|
||||
end
|
||||
|
||||
# clip if a box is specified
|
||||
if box && clip
|
||||
r &= RBA::Region::new(box)
|
||||
sf = layout.dbu / self.dbu
|
||||
if (sf - 1.0).abs > 1e-6
|
||||
r = RBA::Region::new(iter, RBA::ICplxTrans::new(sf.to_f))
|
||||
else
|
||||
r = RBA::Region::new(iter)
|
||||
end
|
||||
|
||||
# clip if a box is specified
|
||||
if box && clip
|
||||
r &= RBA::Region::new(box)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -4690,7 +4748,12 @@ CODE
|
|||
|
||||
cat = @output_rdb.create_category(args[0].to_s)
|
||||
args[1] && cat.description = args[1]
|
||||
@output_rdb.create_items(@output_rdb_cell_id, cat.rdb_id, RBA::CplxTrans::new(self.dbu), data)
|
||||
|
||||
if data.is_a?(RBA::RecursiveShapeIterator)
|
||||
@output_rdb.create_items(@output_rdb_cell_id, cat.rdb_id, data)
|
||||
else
|
||||
@output_rdb.create_items(@output_rdb_cell_id, cat.rdb_id, RBA::CplxTrans::new(self.dbu), data)
|
||||
end
|
||||
|
||||
else
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ TEST(1)
|
|||
"source(\"%s\", \"TOP\")\n"
|
||||
"target(\"%s\", \"TOP\")\n"
|
||||
"l1 = input(1, 0)\n"
|
||||
"l1t = labels(1, 0)\n"
|
||||
"l2 = input(2, 0)\n"
|
||||
"l3 = input(3, 0)\n"
|
||||
"l1.output(1, 0)\n"
|
||||
|
|
@ -46,6 +47,7 @@ TEST(1)
|
|||
"l3.output(3, 0)\n"
|
||||
"l1.space(0.5, projection).output(10, 0)\n"
|
||||
"(l2 & l3).output(11, 0)\n"
|
||||
"l1t.output(20, 0)\n"
|
||||
, input, output)
|
||||
);
|
||||
drc.set_interpreter (lym::Macro::DSLInterpreter);
|
||||
|
|
|
|||
|
|
@ -152,6 +152,15 @@ See <a href="/about/drc_ref_source.xml#input">Source#input</a> for a description
|
|||
<ul>
|
||||
<li><tt>is_tiled?</tt></li>
|
||||
</ul>
|
||||
<h2>"labels" - Gets the labels (text) from an original layer</h2>
|
||||
<keyword name="labels"/>
|
||||
<a name="labels"/><p>Usage:</p>
|
||||
<ul>
|
||||
<li><tt>labels</tt></li>
|
||||
</ul>
|
||||
<p>
|
||||
See <a href="/about/drc_ref_source.xml#labels">Source#labels</a> for a description of that function.
|
||||
</p>
|
||||
<h2>"layers" - Gets the layers contained in the default source</h2>
|
||||
<keyword name="layers"/>
|
||||
<a name="layers"/><p>Usage:</p>
|
||||
|
|
|
|||
|
|
@ -179,9 +179,7 @@ Here is a slow equivalent of the rotated method
|
|||
<pre>
|
||||
# Rotates by 45 degree
|
||||
t = <class_doc href="DCplxTrans">DCplxTrans</class_doc>(1.0, 45.0, false, <class_doc href="DVector">DVector</class_doc>::new)
|
||||
new_layer = layer.collect do |polygon|
|
||||
polygon.transformed(t)
|
||||
end
|
||||
new_layer = layer.collect { |polygon| polygon.transformed(t) }
|
||||
</pre>
|
||||
</p>
|
||||
<h2>"collect_to_edge_pairs" - Transforms a layer into edge pair objects</h2>
|
||||
|
|
@ -239,7 +237,7 @@ The options available are:
|
|||
<li><b>as_dots </b>: with this option, point-like edges will be produced instead of small boxes </li>
|
||||
</ul>
|
||||
</p><p>
|
||||
The following image shows the effect of this method
|
||||
The following images show the effect of this method:
|
||||
</p><p>
|
||||
<table>
|
||||
<tr>
|
||||
|
|
@ -1518,9 +1516,7 @@ apply to this method.
|
|||
Here is a (slow) equivalent of the area selection method:
|
||||
</p><p>
|
||||
<pre>
|
||||
new_layer = layer.select do |polygon|
|
||||
polygon.area >= 10.0
|
||||
end
|
||||
new_layer = layer.select { |polygon| polygon.area >= 10.0 }
|
||||
</pre>
|
||||
</p>
|
||||
<h2>"select_inside" - Selects shapes or regions of self which are inside the other region</h2>
|
||||
|
|
|
|||
|
|
@ -95,6 +95,33 @@ Some filter expressions are:
|
|||
not have names)</li>
|
||||
</ul>
|
||||
</p>
|
||||
<h2>"labels" - Gets the labels (texts) from an input layer</h2>
|
||||
<keyword name="labels"/>
|
||||
<a name="labels"/><p>Usage:</p>
|
||||
<ul>
|
||||
<li><tt>source.labels(layer)</tt></li>
|
||||
<li><tt>source.labels(layer, datatype)</tt></li>
|
||||
<li><tt>source.labels(layer_into)</tt></li>
|
||||
<li><tt>source.labels(filter, ...)</tt></li>
|
||||
</ul>
|
||||
<p>
|
||||
Creates a layer with the labels from the given layer of the source.
|
||||
The layer can be specified by layer and optionally datatype, by a <class_doc href="LayerInfo">LayerInfo</class_doc>
|
||||
object or by a sequence of filters.
|
||||
Filters are expressions describing ranges
|
||||
of layers and/or datatype numbers or layer names. Multiple filters
|
||||
can be given and all layers matching at least one of these filter
|
||||
expressions are joined to render the label collection. See "input" for
|
||||
more details about the input layer specification.
|
||||
</p><p>
|
||||
Label layers currently can only be passed to an output layer.
|
||||
Processing of labels is not supported. See "texts" for a way to filter
|
||||
texts and use the text locations in geometrical operations.
|
||||
</p><p>
|
||||
<pre>
|
||||
labels(1, 0).output(100, 0)
|
||||
</pre>
|
||||
</p>
|
||||
<h2>"layers" - Gets the layers the source contains</h2>
|
||||
<keyword name="layers"/>
|
||||
<a name="layers"/><p>Usage:</p>
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -801,7 +801,7 @@ class RDB_TestClass < TestBase
|
|||
cat1 = rdb.create_category("l1")
|
||||
cell1 = rdb.create_cell("c1")
|
||||
c0.shapes(l1).each do |s|
|
||||
rdb.create_item(cell1.rdb_id, cat1.rdb_id, s, RBA::CplxTrans::new(ly.dbu))
|
||||
rdb.create_item(cell1.rdb_id, cat1.rdb_id, RBA::CplxTrans::new(ly.dbu), s)
|
||||
end
|
||||
assert_equal(cat1.num_items, 1)
|
||||
cn = []
|
||||
|
|
@ -811,7 +811,7 @@ class RDB_TestClass < TestBase
|
|||
rdb = RBA::ReportDatabase.new("neu")
|
||||
cat1 = rdb.create_category("l1")
|
||||
cell1 = rdb.create_cell("c1")
|
||||
rdb.create_items(cell1.rdb_id, cat1.rdb_id, c0.shapes(l1), RBA::CplxTrans::new(ly.dbu))
|
||||
rdb.create_items(cell1.rdb_id, cat1.rdb_id, RBA::CplxTrans::new(ly.dbu), c0.shapes(l1))
|
||||
assert_equal(cat1.num_items, 1)
|
||||
cn = []
|
||||
rdb.each_cell { |c| cn << c.to_s_items }
|
||||
|
|
|
|||
Loading…
Reference in New Issue