Reading in a GDS with multiple child cells and performing transformations

Hi,

While I have been drawing GDS using the Ruby code successfully for a while, this is the first time I am trying to manipulate existing GDS by opening the existing file and manipulating the cells. After struggling for a couple days, I am realizing that I do not quite understand the format of the "shape" I am trying to manipulate and hence would like to request some help.

I read the documentation below but am still struggling:
https://klayout.de/doc-qt4/code/class_Shape.html

The GDS is structured as:

TOPCELL

  • CELL00
  • CELL01
  • CELL02
  • etc.

Hence I open the GDS and select the TOPCELL with "Show As New Top" and try to run the code below. Each CELLxx has shapes only on one layer (0,0). After transformations, I wanted the shapes on (1,0) layer.

Any help/pointers would be most appreciated.

Thanks,

Vikas

module MyMacro
  include RBA
  lv = Application.instance.main_window.current_view
  ly = lv.active_cellview.layout
  top_cell_idx = lv.active_cellview.cell.cell_index
  top_cell_name = ly.cell(top_cell_idx).name
  ly.dbu = 0.001
  dxf = ly.layer(RBA::LayerInfo::new(0, 0))
  wg0 = ly.layer(RBA::LayerInfo::new(1, 0))

  ly.each_cell do |cell|
    next if cell.name == top_cell_name
    cell_name = ly.cell_name(cell.cell_index)

    si = ly.begin_shapes(ly.cell_by_name(cell_name), 0)
    while !si.at_end?
      # for each shape here, I would like to size each shape, move to a new layer and rotate by 90 degrees
      # not necessarily in that order as long as all transformations are done by the end
      # I tried various options including the line below but get an error

      # Should I be transferring each shape to a hull and then do the transformations??
      #     si_hull = si.shape
      #     poly1 = RBA::Trans::new(2, false, 0, 0).trans(si_hull)
      #     cell.shapes(wg0).insert(poly1)

      # OR

      # Performing transformations directly on the individual shapes??
      #     si.shape.transform(RBA::Trans::R90.trans(RBA::Point::new(0, 0)))

      # Please note that I want to write these manipulated shapes back in the same cell and delete the old shapes

      si.next
    end

    lv.add_missing_layers
    lv.select_cell(cell.cell_index, 0)
    lv.zoom_fit
  end
end

Comments

  • Hi All,

    Any pointers or examples on the usage of the "shape" class would be much appreciated?

    Thanks,

    Vikas

  • Hi All,

    I was finally able to figure this one out. I am writing this in case someone needs this in future. Below is the code I added in the loop. It assigns each shape in the cell to poly1 iteratively, sizes the shape by 6µm, does a Boolean and then inserts the shape poly on the layer 1 (defined as "wg0" above).

    Other transformations can be added as appropriate.

    Enjoy!

    Vikas

      poly1 = si.shape.polygon
      poly2 = poly1.sized(6000.0, 0, 2)
      poly3 = RBA::Region::new(poly2) - RBA::Region::new(poly1)
      cell.shapes(wg0).insert(poly3)
    
  • Hi Vikas,

    sorry for the late reply and for sharing the code!

    You can also achieve this without a loop using RBA::Region objects. Region objects can cover all shapes from a layer. Basically you can write:

    ly.each_cell do |cell|
      next if cell.name == top_cell_name
      region1 = RBA::Region::new(cell.shapes(dxf))
      region2 = region1.sized(6000, 0, 2)
      cell.shapes(wg0).insert(region2 - region1)
    end
    

    I assume you want to translate "dxf" to "wg0".

    One more remark:

        si = ly.begin_shapes(ly.cell_by_name(cell_name), 0)
    

    would take the shapes from layer index 0 - this is undefined. You should either use "dxf" or "wg0" which is the index of the layer defined by these variables.

    Regards,

    Matthias

  • Thanks Matthias! No worries about the delayed response. I am always looking to make the code more efficient and so the pointers are most appreciated!

    Thanks,

    Vikas

Sign In or Register to comment.