Compute Layer Area
false
false
true
calc_area
tools_menu.end
ruby
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# DESCRIPTION: Compute total area of all shapes on a layer.
#
# Run the script with
# klayout -rm calc_area_hier.lym ...
# or put the script as "calc_area_hier.lym" into the installation path (on Unix for version <=0.21:
# set $KLAYOUTPATH to the installation folder).
#
# The script will install a new menu item in the Tools menu: "Compute Layer Area".
# It will compute the area of all shapes (not considering overlaps) of the selected layer in the current cell.
#
class CellCount
def initialize(layout, cell)
@layout = layout
@cell = cell
@called_cells = {}
cell.called_cells.each do |c|
@called_cells[c] = true
end
@called_cells[cell.cell_index] = true
@cache = {}
end
def inst_count(cell)
n = @cache[cell.cell_index]
if !n
cell.each_parent_inst do |pi|
if @called_cells[pi.parent_cell_index]
n ||= 0
n += pi.inst.size * inst_count(@layout.cell(pi.parent_cell_index))
end
end
n ||= 1
@cache[cell.cell_index] = n
end
return n
end
private
@layout
@cell
@called_cells
@cache
end
# Main functionality
app = RBA::Application.instance
mw = app.main_window
lv = mw.current_view
if !lv
raise "No view selected"
end
cv = lv.active_cellview
if !cv || !cv.is_valid?
raise "No cell selected"
end
sel_layers = lv.selected_layers
if !sel_layers || sel_layers.size == 0
raise "No layer(s) selected"
end
cc = CellCount::new(cv.layout, cv.cell)
t = "Area of layers in um^2:\n\n"
sel_layers.each do |l|
li = l.current.layer_index
if cv.layout.is_valid_layer?(li)
cells = cv.cell.called_cells
cells.push(cv.cell.cell_index)
atot = 0
cells.each do |ci|
c = cv.layout.cell(ci)
a = 0
c.shapes(li).each do |s|
if s.is_path? || s.is_polygon? || s.is_box?
a += s.polygon.area
end
end
atot += cc.inst_count(c) * a
end
t += sprintf(" %-10s\t", l.current.source(true).to_s) + sprintf("%.2f", (atot * cv.layout.dbu * cv.layout.dbu)) + "\n"
end
end
RBA::MessageBox.info("Calculated Area Per Layer", t, RBA::MessageBox::b_ok)