heitzmann / gdstk

Gdstk (GDSII Tool Kit) is a C++/Python library for creation and manipulation of GDSII and OASIS files.
https://heitzmann.github.io/gdstk/
Boost Software License 1.0
343 stars 86 forks source link

FlexPath Boolean Logic #41

Closed twildi closed 3 years ago

twildi commented 3 years ago

I had to create a checkerboard pattern and tough I'd use two FlexPaths and some boolean logic and I ran into some odd behaviors. Bellow I've shown the result by putting each polygon on a different layer. I'm not sure whether this is supported by the GDSII specifications or not, but multiple squares form a single polygon by connecting through the corners. Also the green polygon has some zero width segments at the bottom. I'm only mentioning this because our EBL machine did not handle it properly and overexposed the whole thing.

image

Code to reproduce:

import gdstk
import numpy as np

lib = gdstk.Library()
cell = gdstk.Cell('TOP')

path1 = gdstk.FlexPath((0,0), np.ones((6,)), 2*np.arange(0,6) + 0.5)
path1.horizontal(11)

path2 = gdstk.FlexPath((0,0), np.ones((6,)), -2*np.arange(0,6) - 0.5)
path2.vertical(11)

polys = gdstk.boolean(path1, path2, 'xor')

for i, poly in enumerate(polys):
    poly.layer = i

cell.add(*polys)

lib.add(cell)
lib.write_gds('gdstk_issue_41.gds')

I can easily generate the squares individually to avoid the issue but I though I'd bring it up.

heitzmann commented 3 years ago

@twildi This is supported by the GDSII specification, but I understand that it looks weird. Boolean operations can give such results, it's hard to control how the polygons will be split in the end when they touch at a single vertex. Boolean is also a very slow operation, so I'd advise against using it unless it is your only solution.

In your case, Repetition will make your code much simpler, faster and reduce the file size:

cell = gdstk.Cell("TOP")

square1 = gdstk.rectangle(1 + 0j, 2 + 1j)
square1.repetition = gdstk.Repetition(5, 6, spacing=(2, 2))

square2 = gdstk.rectangle(1j, 1 + 2j)
square2.repetition = gdstk.Repetition(6, 5, spacing=(2, 2))

cell.add(square1, square2)
twildi commented 3 years ago

@heitzmann I suspected that was indeed the case. Thank you for the tip, I'll try to avoid boolean logic in the future. Performance is not really an issue right now but these zero-width polygons seem to mess-up the beam path of our system.