Merge all shapes of a certain layer of a cell

edited September 2015 in General

Hello Matthias,

I have a small problem. I want to merge all shapes of a certain layer of a cell. All shapes are already polygons. I am not sure how to do it, since you usually need an array of polygons for the merge command. The only way I know of to adress the shapes needed would be:

cell_name.each_shape(layer_name) do |shape|
  xxx
end 

But with this method I dont know how to proceed.

Another idea I tried was with the ShapeProcessor. It looks like:

processor = RBA::ShapeProcessor.new
processor.merge_to_polygon(cell_name.shapes(layer_name), 0, true, false)

The last command needs an array as argument. But the "cell.shapes()" command should give us a list of shapes according to the class documentation. Isn't a list of shapes equivalent to the required array?

Thanks for your help in advance!

Greetings,
Elias

Comments

  • edited November -1

    I found the simplest solution for my problem:

    processor = RBA::ShapeProcessor.new
    processor.merge(layout, cell_name, layer_name, shape-container, false ,0,false,true)
    

    The problem at hand is solved, but just out of curiosity, I would still like to know how to make the list of shapes ( gained by: cell_name.shapes(layer_name)) to an array to use it for the command stated in the previous comment.

    Thanks again,
    Elias

  • edited September 2015

    Hi Elias,

    You can turn a Shapes container into a Shape array with a loop:

    shape_array = []    # will become and array of Shape objects
    shapes = ...        # a Shapes object
    shapes.each { |s| shape_array << s }
    

    But this is not really efficient and when you have a hierarchy of cells, this loop will just convert one cell, not it's children.

    Actually ShapeProcessor is a bit limited in it's use as is it's brother EdgeProcessor. The reasoning behind EdgeProcessor and ShapeProcessor is that the former operates on raw objects (Polygon, Edge, ...) while the latter works on the more generic Shape objects. Both classes implement polygon boolean operations. They allow a great degree of control what you do, but they are a bit unhandy.

    I'd recommend using the newer Region and Edges objects which act as polygon and edge containers and support higher level operations through their methods. Both can be created from a real layout using the RecursiveShapeIterator which is a powerful tool to address the shapes from cell trees or subtrees:

    cell = ....    # a Cell which you want to take the polygons from
    layer = ....   # the layer index from which you want to take the polygons
    
    # creates a region containing all polygons from the cell's layer plus all the
    # polygons from it's children.
    region = RBA::Region::new(cell.begin_shapes_rec(layer))
    
    # merges the polygons (in-place: the region is filled with the merged polygons)
    region.merge
    
    # clears the input layer (in all cells) and puts the 
    # merged polygons back into the cell
    cell.layout.clear_layer(layer)
    cell.shapes(layer).insert(region)
    

    The Edges class allows handling of edges (the connecting lines of the polygon vertexes). There is a rich set of methods on these containers you may like to explore. In fact, the DRC engine is built around these two objects mainly and is implemented as a thin wrapper around these. In Region and Edges you have access to these methods without your code.

    If you want to script layout manipulations alone, the DRC feature may be easier to use because it wraps all the overhead of retrieving and storing polygons. Merging a layer in a DRC script looks like this:

    # Merges the polygons on layer 10, datatype 0:
    input(10).merged.output(10)
    

    Matthias

  • edited November -1

    Thank you Matthias for your thorough answer. I will look into these objects.

Sign In or Register to comment.