Hello Everyone,
I recently looked at the area script which I was able to use in KLayout. Now I am trying to find the perimeter of shapes (some shapes even have curves) in KLayout. When I copy and paste the code that was provided in this forum, it doesn't work. I get a lot of errors about 'db' and it doesn't recognize many of the methods such as begin_edge(), etc.
SO I tried making my own code, and I am unsuccessful. I was wondering if someone could take a look at it for me, and let me know where I am going wrong.
Thanks in advance, Natalie
class MenuAction < RBA::Action
def initialize( title, shortcut, &action )
self.title = title
self.shortcut = shortcut
@action = action
end
def triggered
@action.call( self )
end
private
@action
end
$compute_total_perimeter = MenuAction.new( "Compute perimeter of selected shapes", "" ) do
app = RBA::Application.instance
mw = app.main_window
lv = mw.current_view
if lv == nil
raise "No view selected"
end
total_perimeter = 0.0
lv.each_object_selected do |obj|
shape = obj.shape
layout = lv.cellview(obj.cv_index).layout
if shape.is_polygon? || shape.is_box? || shape.is_path?
poly=shape.path
shape.each_point
edge=poly.path_bgnext
while (edge!=poly.path_endext)
total_perimeter+=edge.path_width
end
end
RBA::MessageBox.info("Total points", "Total points of selected object is #{total_perimeter} microns", RBA::MessageBox.b_ok)
end
app = RBA::Application.instance
mw = app.main_window
menu = mw.menu
menu.insert_separator("tools_menu.end", "name")
menu.insert_item("tools_menu.end", "compute_total_perimeter", $compute_total_perimeter)
Comments
Hi Natalie,
please see me comments in the other forum entry. The problem was that this this discussion was basically about C++ code and you can't mix that with Ruby.
Here is the correct code:
Regards,
Matthias
The code runs and works, but there is one a slight problem. The calculated perimeter is always 1000 times larger than the actual perimeter...
Is it possible that it doesn't know when the final edge is?
Thanks again for all your help, Natalie
Here is now my corrected code. Thanks again Matthias!
class MenuAction < RBA::Action
def initialize( title, shortcut, &action )
self.title = title
self.shortcut = shortcut
@action = action
end
def triggered
@action.call( self )
end
private
@action
end
$compute_total_perimeter = MenuAction.new( "Compute total perimeter of selected shape", "" ) do
app = RBA::Application.instance
mw = app.main_window
lv = mw.current_view
if lv == nil
raise "No view selected"
end
total_perimeter = 0.0
lv.each_object_selected do |obj|
shape = obj.shape
layout = lv.cellview(obj.cv_index).layout
if shape.is_polygon? || shape.is_box? || shape.is_path?
shape.polygon.each_edge { |e| total_perimeter += e.length*obj.trans.mag*layout.dbu }
end
end
RBA::MessageBox.info("Total perimeter", "Total perimeter of selected object is #{total_perimeter} microns", RBA::MessageBox.b_ok)
end
app = RBA::Application.instance
mw = app.main_window
menu = mw.menu
menu.insert_separator("tools_menu.end", "name")
menu.insert_item("tools_menu.end", "compute_total_perimeter", $compute_total_perimeter)
Hi Natalie,
yes you're right, The DBU multiplication is doing the trick and again you're right that you have to take the magnification in the instantiation path into account. I forgot that. Thank you for the hint.
Just to add some final remark: you can optimize the perimeter loop somewhat by doing the multiplication outside the loop. Ruby is not a fast language, so that might be a good idea:
Regards,
Matthias