Convert shapes in a layer to polygon and round corners

edited July 2015 in General
Hello Matthias,
I am new to this programm and i have a little problem, which I hope you can help me with.

In a child-cell I have several layers. Each layer contains some shapes. These shapes should all be polygons. My final goal is to round the corners of these polygons. I want to round the corners at this point, because I did some boolean layer operations before, which inevitably produced some sharp corners.

My idea was to adress these shapes first with the cell.each_shape command. Then i wanted to round the corners of these shapes with the polygon.round_corners command. I got a little confused of how to adress these shapes to perform the polygon.round_corners command, but I tried the following:


cell2_dioden.each_shape($layerpplus) do |shape|
shape.replace(Shape shape, Polygon polygon)
Polygon=polygon.round_corners(50,50,17)
end

I tried to stick with the class-documentation, but these few lines produce 2 Errors. 1 Syntax error in the 2nd line and one dynamic constant assignment error in the 3rd one.

Do you have any idea how to deal with this issue?

Thanks in advance,
Elias

P.S. how do you post your code correctly here in this forum? I couldnt find any information on this website.

Comments

  • edited July 2015

    To format code, choose Markdown radio button and indent each line by at least four spaces

    This line has four spaces in front of it
      This line has six spaces
        This line has eight spaces
    

    To do that easily, select all code in KLayout's macro editor, press tab twice, press copy, press undo (Ctrl-Z) twice to restore the code to what it was, then come to your browser and press paste.

    http://daringfireball.net/projects/markdown/syntax

    Here is your code reformatted

    cell2_dioden.each_shape($layerpplus) do |shape|
      shape.replace(Shape shape, Polygon polygon) 
      Polygon=polygon.round_corners(50,50,17)
    end
    

    Couple low-importance notes: Ruby variable names should be lowercase "snake_case", and you probably don't need $layerpplus to be a global variable -- Dollar-sign is rarely needed (except maybe for global constants not global variables, but even then it often doesn't need to be global).

    Anyway to get to the core of your question: There is no .replace method in class Shape; when you put arguments you just put the variable name without type declaration (e.g. no "Shape" with capital S), and you need to put the 50,50,17 in database units instead of microns.

    I took the Core > Convert to polygon code from this zip file and added two lines to round the corners. But it can be done in one line, I just put two lines for clarity. If you need it to act on cell rather than on selection, you can play around and modify it. If you get stuck, post back here.

    include RBA
    app = Application.instance
    mw = app.main_window
    lv = mw.current_view
    raise "No view selected" if lv.nil?
    ly = lv.active_cellview.layout
    dbu = ly.dbu
    
    ri,ro,n = 50/dbu,50/dbu,17/dbu # Divide by dbu to convert from um to database units (which are integers)
    
    lv.transaction("Convert to polygon then round")
    
    begin
    
      lv.each_object_selected { |obj|
    
        if !obj.is_cell_inst?
          shape = obj.shape
    
          if shape.is_box?
    
            box = shape.box
            left,bott,right,top = box.left, box.bottom, box.right, box.top
            pts = []
            pts << Point.new(left,bott)
            pts << Point.new(right,bott)
            pts << Point.new(right,top)
            pts << Point.new(left,top)
            polygon = Polygon.new(pts)
    
            shape.polygon = polygon # polygon= method replaces the shape with that polygon while preserving user properties.
    
          elsif shape.is_path?
            shape.polygon = shape.path.polygon # polygon= method replaces the shape with that polygon while preserving user properties. 
          end
    
          # Now that we have a polygon we round the corners
          new_polygon = shape.polygon.round_corners(ri,ro,n)
          shape.polygon = new_polygon
        end  
      }
    
    ensure
      lv.commit
    end
    
  • edited July 2015

    Hello davidnhutch,

    thank you for your quick reply and all the answers!
    The problem could now be resolved.

    I did not want to adress all objects in the layout, but only the shapes of a specific layer of a specific cell. But because of your script i realized, my shapes were already polygons. So the only thing which I needed to do was to adress the shapes properly and round the corners. The final code to resolve my problem is the following:

    cell2_dioden.each_shape($layerpplus) do |shape|
    
      new_polygon=shape.polygon.round_corners(Functions.convert(para['implant_radius']),Functions.convert(para['implant_radius']), 102)
      shape.polygon=new_polygon
    
    end
    

    Thanks a lot

    Greetings
    Elias

  • edited November -1

    Hi David,

    perfect support! Thank you very much.

    Matthias

Sign In or Register to comment.