gdstk 布尔值太慢但在 Klayout 中运行速度很快?

问题描述 投票:0回答:1

我正在尝试在一个矩形上切出几个洞。当我在 Klayout 中使用“从第一个值减去其他值”执行此操作时,结果几乎立即计算出来。但是,当我尝试使用 gdstk 执行此操作时,速度非常慢!我做错了什么吗?

Klayout GUI 布尔操作以某种方式工作得非常快,因为我通过多重选择一次性选择所有要切割的多边形。我怀疑这与我使用 gdstk 执行的每个剪切操作的顺序 for 循环更新不同。在 gdstk 中是否有更智能+更快的方法来做到这一点?非常感谢您的帮助!

import gdstk

# parameters for the design

dc =5.8
eps = 1/20
cW=2000
d = 70
cL = 10000
g = dc/(1.4*(eps)**0.48) 

# create gds library and cells

lib = gdstk.Library()
pD = lib.new_cell("post")
pRow = lib.new_cell("pArray")
pRef = lib.new_cell("pRef")
clip = lib.new_cell("clip")
inv = lib.new_cell("invDld")

# construct geometries 

pD.add(gdstk.ellipse((0,0), d/2, tolerance=0.01))   # unit cell for array
box = gdstk.rectangle((-cL/2,-cW/2),(cL/2,cW/2))    # box to cut from

ny = int(cL / (g + d)) + 1                  # ncols
nx = int(cW / (g + d)) + 1                #  nrows
spc = d + g                                      # array spacing
extras = int(ny*eps) + 1

# create array 

for i in range(ny):
    arr = gdstk.Reference(pD, origin = (i*spc,i*eps*spc - extras*spc), columns = 1, rows= nx + extras, spacing = (0,spc))
    pRow.add(arr) 
rowRef = gdstk.Reference(pRow, origin = (-cL/2,-cW/2), columns = 1, rows= 1, spacing = (0,0))
pRef.add(rowRef)

 # mask to trim off edges

mask = gdstk.boolean(gdstk.offset(box, (extras+2)*spc)[0], box, 'not')[0]

# remove posts that fall outside box

pols = pRef.flatten().polygons
for i in range(len(pols)):                                 <<<<  This is also relatively slow
    res = gdstk.boolean(pols[i], mask, 'not')               
    if res != []:
        if res[0].area() > 25:
            clip.add(res[0])
clip.add(box)                                                             # cell containing mask and objects to cut

lib.remove(pRef, pRow, pD)                                              # remove unwanted cells

# flatten structures to perform boolean cut

clipFlat = clip.flatten()
pols = clipFlat.polygons

# perform inversion! This is where it fails <<<<<<<<<<<<<<<

res = gdstk.boolean(box,pols, "not")[0]
inv.add(res)

lib.write_gds("minimalExample.gds")

我也尝试过简单地使用

res = gdstk.boolean(box,pols, "not")[0]

正如您在上面的最小示例中看到的,这会返回一个空列表,这不是正确的输出。

python layout boolean mask cut
1个回答
0
投票

删除线

clip.add(box)
即可解决问题。然而,从掩码中删除 pRef polgon 的代码的前面部分仍然需要在 for 循环中执行。没有这个我就无法运行......

导入gdstk

# parameters for the design

dc =5.8
eps = 1/20
cW=2000
d = 70
cL = 10000
g = dc/(1.4*(eps)**0.48) 

# create gds library and cells

lib = gdstk.Library()
pD = lib.new_cell("post")
pRow = lib.new_cell("pArray")
pRef = lib.new_cell("pRef")
clip = lib.new_cell("clip")
inv = lib.new_cell("invDld")

# construct geometries 

pD.add(gdstk.ellipse((0,0), d/2, tolerance=0.01))   # unit cell for array
box = gdstk.rectangle((-cL/2,-cW/2),(cL/2,cW/2))    # box to cut from

ny = int(cL / (g + d)) + 1                  # ncols
nx = int(cW / (g + d)) + 1                #  nrows
spc = d + g                                      # array spacing
extras = int(ny*eps) + 1

# create array 

for i in range(ny):
    arr = gdstk.Reference(pD, origin = (i*spc,i*eps*spc - extras*spc), columns = 1, rows= nx + extras, spacing = (0,spc))
    pRow.add(arr) 
rowRef = gdstk.Reference(pRow, origin = (-cL/2,-cW/2), columns = 1, rows= 1, spacing = (0,0))
pRef.add(rowRef)

 # mask to trim off edges

mask = gdstk.boolean(gdstk.offset(box, (extras+2)*spc)[0], box, 'not')[0]

# remove posts that fall outside box

pols = pRef.flatten().polygons
for i in range(len(pols)):                                 <<<<  This is also relatively slow
    res = gdstk.boolean(pols[i], mask, 'not')               
    if res != []:
        if res[0].area() > 25:
            clip.add(res[0])

lib.remove(pRef, pRow, pD)                                              # remove unwanted cells

# flatten structures to perform boolean cut

clipFlat = clip.flatten()
pols = clipFlat.polygons

# perform inversion! This is where it fails <<<<<<<<<<<<<<<

res = gdstk.boolean(box,pols, "not")[0]
inv.add(res)

lib.write_gds("minimalExample.gds")
© www.soinside.com 2019 - 2024. All rights reserved.