-
-
Notifications
You must be signed in to change notification settings - Fork 126
Invert Entire GDS File #68
Comments
Yes, you'll have to do a Boolean operation to subtract the existing geometry from a large enough rectangle (or whatever shape you prefer). Keep in mind that Boolean operations are computationally expensive, so it could take a long time to process depending on the number of vertices and polygons in the file. Here is an example: import gdspy
# Sample GDSII
c0 = gdspy.Cell('REF')
c0.add(gdspy.Rectangle((-2, -2), (2, 2)))
c1 = gdspy.Cell('MAIN')
c1.add(gdspy.Round((0, 0), 10, inner_radius=8))
c1.add(gdspy.Rectangle((0, 0), (20, 10)))
c1.add(gdspy.CellReference(c0, magnification=2))
c1.add(gdspy.CellArray(c0, 5, 5, (10, 10), (0, -20), rotation=45))
# Find bounding box and expand it by `margin`
margin = 2
p0, p1 = c1.get_bounding_box()
p0 = (p0[0] - margin, p0[1] - margin)
p1 = (p1[0] + margin, p1[1] + margin)
# Invert cell MAIN
c2 = gdspy.Cell('INV')
c2.add(gdspy.fast_boolean(gdspy.Rectangle(p0, p1), c1.get_polygons(), 'not'))
gdspy.LayoutViewer() |
Dear Lucas thanks a lot for your answer. In my case, my gds file contains many cells and cell arrays. This is done as to create a memory efficient gds file. Here is an example:
Then... how can I invert it ? |
The example I showed before includes reference arrays. It works for any GDS layout. |
Oh, please excuse me... I somehow missed that. Thanks a lot !! Yes ! It works ! Very nice ! Just one more follow up question: As you can see in your example there is a lot of space added when inverting the gds, because we apply the boolean to a simple rectangle. Do you think that it would be possible to create a border which traces along the shape of the gds file and then to use that to invert it ? Do you see what I mean ? |
It's hard to properly define a border and guarantee connectivity, if that's what you're looking for. You can use the import gdspy
# Sample GDSII
c0 = gdspy.Cell('REF')
c0.add(gdspy.Rectangle((-2, -2), (2, 2)))
c1 = gdspy.Cell('MAIN')
c1.add(gdspy.Round((0, 0), 20, inner_radius=10))
c1.add(gdspy.Rectangle((0, 0), (20, 10)))
c1.add(gdspy.CellReference(c0, magnification=2))
c1.add(gdspy.CellArray(c0, 5, 5, (10, 10), (0, -20), rotation=45))
# Create an envolope by offseting the whole geometry
envelope = gdspy.offset(c1.get_polygons(), 2, join_first=True, layer=3)
# Invert cell MAIN
c2 = gdspy.Cell('INV')
c2.add(gdspy.fast_boolean(envelope, c1.get_polygons(), 'not'))
c1.add(envelope)
gdspy.LayoutViewer() Otherwise, you should first get the convex hull of the geometry, and use that for inversion (with a proper offset, as well): import gdspy
import numpy
import scipy.spatial
# Sample GDSII
c0 = gdspy.Cell('REF')
c0.add(gdspy.Rectangle((-2, -2), (2, 2)))
c1 = gdspy.Cell('MAIN')
c1.add(gdspy.Round((0, 0), 20, inner_radius=10))
c1.add(gdspy.Rectangle((0, 0), (20, 10)))
c1.add(gdspy.CellReference(c0, magnification=2))
c1.add(gdspy.CellArray(c0, 5, 5, (10, 10), (0, -20), rotation=45))
# Find convex hull and offset it by some amount
allpoints = numpy.vstack(c1.get_polygons())
hull = scipy.spatial.ConvexHull(allpoints)
envelope = gdspy.offset([allpoints[hull.vertices, :]], 2)
# Invert cell MAIN
c2 = gdspy.Cell('INV')
c2.add(gdspy.fast_boolean(envelope, c1.get_polygons(), 'not'))
gdspy.LayoutViewer() |
No problem! I hope it works well for your case! |
Hi !
Is it possible to invert a complex gds file (to change resist toner) ?
Thanks.
The text was updated successfully, but these errors were encountered: