Shapes with Holes

Hi Matthias

I'm a beginner with Klayout and currently im trying to figure out how to get rid of the extra edge whenever you load in a GDS files with holes, like this.

I am aware that you can somewhat achieve this objective with DRC such as layer.holes and layer.hulls, however when it comes to overlapped shape, these method would merge the two shape into one, and that's not something I want to do.

The goal is to get holes and hull from everysingle shape without merging when they are overlapped.

My current approach is to use python script and iterate through the shape in the layer, and uses polygon.resolve_holes to get the hulls of the polygon. However it seems that the extra edge that it adds to everytime I open the file would make the program think the polygon is a simple polygon even though its not, therefore polygon.resolve_holes is not working, and that's why I wonder if there is a way to get rid of the extra edge that connect holes and the hulls.

Sorry for the rumbling, hopefully im making sense.



  • edited February 2022

    With some help from a friend this is the solution that I wrote

    import pya
    import time
    startTime = time.time()
    view = pya.LayoutView.current()
    cellview =
    layout = cellview.layout()
    #obatin target layer and the source layer
    target_layer = layout.layer(10, 0)
    source_layer = layout.layer(3, 0)
    #get the top cell
    cell_to_add = layout.cell("TOP")
    shapeList = cell_to_add.shapes(source_layer)
    shapeArray = []
    for someShape in shapeList.each():
      #Do some operation for each shape in layer
      #noHoleZone = someShape.polygon.resolve_holes()
    #Uses Overlap to get rid of the line
    for anyShape in shapeArray:
      r1 = pya.Region()
      r2 = pya.Region()
      mergedObject = r1 & r2
    endTime = time.time()
    print("The time of execution of above program is :", endTime - startTime)

    Bascially what I did is to merge every single shape in a layer with themselves then put them on a new layer, and it works. However I wonder if there is a more elegent way to solve this problem, cause I can see the run time gets longer with the gds file getting more complicated. Also I have this feeling that the way how I use r1 and r2 in that loop might cause serious problem and I have no idea if the r1.destroy and r2.destroy even behave the way that I imagine they do.

  • The code is a little more complex than it needs to be.

    If you copy the shapes to a new layer, you do not need to collect the shapes first. This you only need to do if you plan to replace the shapes.

    Plus, you do not need to perform a logical AND ("&" operator) to get the merged polygons. "Region#merge" will do.

    You can also optimize the loop a little to avoid "create + destroy" of the Region objects. Like this:

    r = pya.Region()
    for anyShape in shapeList.each():

    This may be somewhat better in performance. Still it's a (slow) Python loop.

    A faster (C++) loop is this short DRC script:

    l3 = input(3, 0)
    l10 = l3.raw.drc(primary.merged)
    l10.output(10, 0)

    Here is a brief explanation:

    "raw" turns off "merged semantics" for l3. This means, all polygons are considered individually. "drc" is a kind of loop over all shapes - in this case without neighbourhood because there are no measurement functions inside the "drc" function's body. "primary.merged" will be executed for each considered ("primary") shape and "merged" will return the merged polygon.

    To get the hulls only use:

    l3 = input(3, 0)
    l10 = l3.raw.drc(primary.merged.hulls)
    l10.output(10, 0)

    See here for details about "drc":


  • Sorry for the late reply! Thank you very much Matthias, this is very helpful!

    Have a great day!

  • @Matthias

    I wonder if there is a more elegent solution without merging, since merging at times can be very time consuming, and I think in a way it would change the original layout. I am just curious

    Thank you very much!

  • I'm afraid with GDS there is no other elegant solution. The problem is you're basically fighting against a fundamental concept of GDS which is that touching or overlapping polygons are considered to form a large "painted" area. Edges essentially don't matter. That's why introducing the cut line is a valid and quite commonly used technique.

    You can of course adopt another view and decide that for you edges are important matter. After all, GDS is just a data container. But then GDS does not offer you a clean way of generating polygons with holes. The merge step is the only reliable way to rectify this, I'm afraid. Again, your request is somewhat exotic in terms of GDS conventions and that's why optimized tools are not available yet. The DRC loop is the best that KLayout can offer out of the box.


  • I see! Thank you very much for the respond!


Sign In or Register to comment.