FEATURE: 'labels' method in DRC scripts allows copying labels to output layers.

This commit is contained in:
Matthias Koefferlein 2018-04-28 10:36:13 +02:00
parent 86aea962c9
commit ccfe6fa918
10 changed files with 150 additions and 50 deletions

View File

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

View File

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

View File

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

View File

@ -3469,6 +3469,67 @@ 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 = []
@ -3505,35 +3566,10 @@ CODE
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 == "-"
@ -4658,6 +4707,13 @@ CODE
end
end
if labels_only
# for labels layers, the iterator is the data (no region)
r = iter
else
sf = layout.dbu / self.dbu
if (sf - 1.0).abs > 1e-6
r = RBA::Region::new(iter, RBA::ICplxTrans::new(sf.to_f))
@ -4672,6 +4728,8 @@ CODE
end
end
r
end
@ -4690,7 +4748,12 @@ CODE
cat = @output_rdb.create_category(args[0].to_s)
args[1] && cat.description = args[1]
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

View File

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

View File

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

View File

@ -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 &gt;= 10.0
end
new_layer = layer.select { |polygon| polygon.area &gt;= 10.0 }
</pre>
</p>
<h2>"select_inside" - Selects shapes or regions of self which are inside the other region</h2>

View File

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

View File

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