Filling tool using Python

Hello,

I want to use the filling tool in my Python script and for that, I need to translate the following script from Ruby to Python. I have problem with the While loop. Any suggestions?

r = ...        # region to fill
c = ...        # cell in which to produce the fill cells
fc_index = ... # fill cell index
fc_box = ...   # fill cell footprint

fill_margin = RBA::Point::new(0, 0)   # x/y distance between tile cells with different origin

# Iteration: fill a region and fill the remaining parts as long as there is anything left.
# Polygons not worth being considered further are dropped (last argument is nil).
while !r.is_empty?
  c.fill_region(r, fc_index, fc_box, nil, r, fill_margin, nil)
end

Comments

  • Hi, Mo!

    I think while not r.is_empty() is correct translation to Python. Similar to other methods with question mark.

  • @EugeneZelenko
    Many thanks for your help. That solved the while issue but for some reason still the filling does not work!!

     fc_box = pya.DBox(...)   # fill cell footprint
    
        fill_margin = pya.DPoint(self.channel_pitch, 0)   # x/y distance between tile cells with different origin
        
        region = pya.Region(box8(self.metalrf))
        
        # Iteration: fill a region and fill the remaining parts as long as there is anything left.
        # Polygons not worth being considered further are dropped (last argument is nil).
        while not region.is_empty():
          fillshape = self.cell.fill_region(region, circle, fc_box, False, amcp_cell_4, fill_margin, False)
          
          self.cell.shapes(self.metalrf_layer).insert(fillshape)
  • Isn't None Python equivalent of nil?

  • @MoBe @EugeneZelenko is right. You should use "None" instead of "False".

    But there are more issues:

    • DBox isn't the right version for fc_box. Use Box and use DBU coordinates. Same for fill_margin which should be a Vector and use DBU coordinates.
    • "while not region.is_empty():" doesn't make a lot of sense: the region is not modified, hence, while will never terminate
    • "fill_region" does not return anything, so "fillshape" will be undefined

    Make sure that "circle" is a cell index. "amcp_cell_4" needs to be a Region and will receive the remaining parts.

    Matthias

  • edited March 2021

    Thanks very much for your support @Matthias @EugeneZelenko

    @Matthias I understood the first point you made. But I still don't understand how I can fix the while loop so that it will terminate and how I should define "circle" in a way that I can correctly call it on the "fill_region" function. Here is how I defined it.

    n = 200    # number of points
        r = self.channel_radius*1000  # radius
        da = 2 * math.pi / n
        pts = []
        for i in range(0, n):
          pts.append(pya.Point.from_dpoint(pya.DPoint(r * math.cos(i * da), r * math.sin(i * da))))
        circle = pya.Polygon(pts)
        self.cell.shapes(self.metalrf_layer).insert(circle)
    

    Thank you again for the amazing support here.

  • edited March 2021

    MoBe

    I think this is what you after .. ;) :)
    I don't know what your channel_radius is
    so just plugged in a number
    Tracy


    import pya import array import sys import math layout = pya.Application.instance().main_window().current_view().active_cellview().layout() if layout == None: raise Exception("No layout") cv = pya.Application.instance().main_window().current_view().active_cellview() dbu =layout.dbu cell = pya.Application.instance().main_window().current_view().active_cellview().cell if cell == None: raise Exception("No cell") n = 200 # number of points r = 2*1000 # radius da = 2 * math.pi / n def coords(path): result = [] for p in path: result.append(DPoint.new(p[0]/dbu,p[1]/dbu)) return result def create_polygon(crd,lay): layer_info = LayerInfo.new(lay,0) layer_index = layout.layer(layer_info) cv.cell.shapes(layer_index).insert(Polygon.new(crd)) circle = [] for i in range(0, n): path = r * math.cos(i * da), r * math.sin(i * da) circle.append(path) lay = 9 pth = coords(circle) create_polygon(pth,lay)
  • edited March 2021

    @tagger5896 Thanks for the codes. I already defined the circle and it works as it is supposed to. However, the problem is I don't understand in the above scripts, how I should call the circle in the "fill_region" function correctly and how I can stop the loop. Basically, I don't understand the "unsigned int fill_cell_index" written in the documentation for fill_region:

    Signature: void fill_region (const Region region, unsigned int fill_cell_index, const Box fc_box, const Point ptr origin, Region ptr remaining_parts, const Vector fill_margin, Region ptr remaining_polygons)
    
    Description: Fills the given region with cells of the given type (extended version)
    
    region: The region to fill
    fill_cell_index:    The fill cell to place
    fc_box: The fill cell's footprint
    origin: The global origin of the fill pattern or nil to allow local (per-polygon) optimization
    remaining_parts:    See explanation below
    fill_margin:    See explanation below
    remaining_polygons: See explanation below
    

    Another point is what I am trying to build is a PCell, and I don't want to make another cell within my PCell (I am not sure if that is even possible). So, basically, I should make the circle within the Pcell and call it in fill_region function. Hope this makes sense!

    Thanks again.

  • The fill_cell_index is the cell.cell_index() where cell is the pya.Cell object you want to use for filling. And of course it is possible to instantiate other cells within a PCell, where would the fun be without that possibility ;) (you can even instantiate other PCells within a PCell, although I had to bother Matthias a long time until I understood how to do that ^^).

  • @sebastian Thank you for your help. Really appreciate it. However, nothing worked for me to translate the following into python codes, although I was able to do it some other way it is extremely slow because of the loops that it contained! If anyone has an idea, that would be much appreciated!

    r = ...        # region to fill
    c = ...        # cell in which to produce the fill cells
    fc_index = ... # fill cell index
    fc_box = ...   # fill cell footprint
    
    fill_margin = RBA::Point::new(0, 0)   # x/y distance between tile cells with different origin
    
    # Iteration: fill a region and fill the remaining parts as long as there is anything left.
    # Polygons not worth being considered further are dropped (last argument is nil).
    while !r.is_empty?
      c.fill_region(r, fc_index, fc_box, nil, r, fill_margin, nil)
    end
    
    
  • Hello @MoBe

    You should specify the starting point (instead of nil) to make the fill_region work correctly:

    region     = db.Region(db.Box(x_start,y_start,x_end,y_end))
    while not region.is_empty():
                    topcell_o.fill_region(region, input_topcell.cell_index(), db.Box(input_bbox), db.Point(x_start,y_start), region, db.Point(0.0,0.0), None)
    

    The last argument could be set to 'None'.

    Regards,

Sign In or Register to comment.