Geometry#

gdsfactory provides you with some geometric functions

Boolean#

There are several common boolean-type operations available in the geometry library. These include typical boolean operations (and/or/not/xor), offsetting (expanding/shrinking polygons), outlining, and inverting.

The gf.boolean() function can perform AND/OR/NOT/XOR operations, and will return a new geometry with the result of that operation.

import gdsfactory as gf

E = gf.components.ellipse(radii=(10, 5), layer=(1, 0))
R = gf.components.rectangle(size=(15, 5), layer=(2, 0))
C = gf.boolean(A=E, B=R, operation="not", layer1=(1, 0), layer2=(2, 0), layer=(3, 0))
# Other operations include 'and', 'or', 'xor', or equivalently 'A-B', 'B-A', 'A+B'

# Plot the originals and the result
D = gf.Component()
D.add_ref(E)
D.add_ref(R)
D.add_ref(C).dmovex(30)
D.plot()
../_images/ee8808da6209ed49582e5218110da0f81fc586866c2da81d520f8ec6cab57833.png

To learn how booleans work you can try all the different operations not, and, or, xor

import gdsfactory as gf

operation = "not"
operation = "and"
operation = "or"
operation = "xor"

r1 = (8, 8)
r2 = (11, 4)
r1 = (80, 80)
r2 = (110, 40)

angle_resolution = 0.1

c1 = gf.components.ellipse(radii=r1, layer=(1, 0), angle_resolution=angle_resolution)
c2 = gf.components.ellipse(radii=r2, layer=(1, 0), angle_resolution=angle_resolution)
c4 = gf.boolean(c1, c2, operation=operation)
c4.plot()
../_images/b255b928c2adc85763a2aeb645e4c1aae5ee4be1cf67d01af3b09d8a711d3d0b.png

Offset#

import gdsfactory as gf
from gdsfactory.generic_tech import LAYER

c = gf.components.coupler_ring()
c
../_images/dff8466eb2afd2e15c250644a3eec57050670c6fe194642a1000384fcc87796b.png
polygons = c.get_polygons()[LAYER.WG]
polygons
[(-4278,450;-4418,451;-4559,453;-4699,456;-4841,460;-4982,466;-5124,474;-5267,484;-5410,497;-5553,512;-5696,531;-5839,553;-5982,579;-6124,609;-6267,643;-6408,682;-6549,725;-6688,774;-6826,828;-6977,894;-7125,967;-7270,1047;-7411,1132;-7548,1224;-7681,1321;-7809,1425;-7933,1533;-8053,1647;-8167,1767;-8275,1891;-8379,2019;-8476,2152;-8568,2289;-8653,2430;-8733,2575;-8806,2723;-8872,2874;-8926,3012;-8975,3151;-9018,3292;-9057,3433;-9091,3576;-9121,3718;-9147,3861;-9169,4004;-9188,4147;-9203,4290;-9216,4433;-9226,4576;-9234,4718;-9240,4859;-9244,5001;-9247,5141;-9249,5282;-9250,5422;-9250,5700;-8750,5700;-8750,5424;-8749,5286;-8747,5149;-8744,5013;-8740,4877;-8735,4742;-8727,4607;-8718,4473;-8706,4340;-8691,4207;-8674,4075;-8654,3944;-8630,3814;-8603,3685;-8573,3558;-8538,3432;-8500,3308;-8457,3186;-8410,3066;-8352,2934;-8289,2806;-8220,2680;-8146,2558;-8066,2439;-7982,2324;-7892,2212;-7798,2104;-7699,2001;-7596,1902;-7488,1808;-7376,1718;-7261,1634;-7142,1554;-7020,1480;-6894,1411;-6766,1348;-6634,1290;-6514,1243;-6392,1200;-6268,1162;-6142,1127;-6015,1097;-5886,1070;-5756,1046;-5625,1026;-5493,1009;-5360,994;-5227,982;-5093,973;-4958,965;-4823,960;-4687,956;-4551,953;-4414,951;-4276,950;-4000,950;-4000,450),
 (-9000,-250;-9000,250;-4000,250;-4000,-250),
 (0,450;0,950;276,950;414,951;551,953;687,956;823,960;958,965;1093,973;1227,982;1360,994;1493,1009;1625,1026;1756,1046;1886,1070;2015,1097;2142,1127;2268,1162;2392,1200;2514,1243;2634,1290;2766,1348;2894,1411;3020,1480;3142,1554;3261,1634;3376,1718;3488,1808;3596,1902;3699,2001;3798,2104;3892,2212;3982,2324;4066,2439;4146,2558;4220,2680;4289,2806;4352,2934;4410,3066;4457,3186;4500,3308;4538,3432;4573,3558;4603,3685;4630,3814;4654,3944;4674,4075;4691,4207;4706,4340;4718,4473;4727,4607;4735,4742;4740,4877;4744,5013;4747,5149;4749,5286;4750,5424;4750,5700;5250,5700;5250,5422;5249,5282;5247,5141;5244,5001;5240,4859;5234,4718;5226,4576;5216,4433;5203,4290;5188,4147;5169,4004;5147,3861;5121,3718;5091,3576;5057,3433;5018,3292;4975,3151;4926,3012;4872,2874;4806,2723;4733,2575;4653,2430;4568,2289;4476,2152;4379,2019;4275,1891;4167,1767;4053,1647;3933,1533;3809,1425;3681,1321;3548,1224;3411,1132;3270,1047;3125,967;2977,894;2826,828;2688,774;2549,725;2408,682;2267,643;2124,609;1982,579;1839,553;1696,531;1553,512;1410,497;1267,484;1124,474;982,466;841,460;699,456;559,453;418,451;278,450),
 (0,-250;0,250;5000,250;5000,-250),
 (-4000,450;-4000,950;0,950;0,450),
 (-4000,-250;-4000,250;0,250;0,-250),
 (-12000,-250;-12000,250;-9000,250;-9000,-250),
 (5000,-250;5000,250;8000,250;8000,-250)]
r = gf.kdb.Region(polygons)
r
(-4278,450;-4418,451;-4559,453;-4699,456;-4841,460;-4982,466;-5124,474;-5267,484;-5410,497;-5553,512;-5696,531;-5839,553;-5982,579;-6124,609;-6267,643;-6408,682;-6549,725;-6688,774;-6826,828;-6977,894;-7125,967;-7270,1047;-7411,1132;-7548,1224;-7681,1321;-7809,1425;-7933,1533;-8053,1647;-8167,1767;-8275,1891;-8379,2019;-8476,2152;-8568,2289;-8653,2430;-8733,2575;-8806,2723;-8872,2874;-8926,3012;-8975,3151;-9018,3292;-9057,3433;-9091,3576;-9121,3718;-9147,3861;-9169,4004;-9188,4147;-9203,4290;-9216,4433;-9226,4576;-9234,4718;-9240,4859;-9244,5001;-9247,5141;-9249,5282;-9250,5422;-9250,5700;-8750,5700;-8750,5424;-8749,5286;-8747,5149;-8744,5013;-8740,4877;-8735,4742;-8727,4607;-8718,4473;-8706,4340;-8691,4207;-8674,4075;-8654,3944;-8630,3814;-8603,3685;-8573,3558;-8538,3432;-8500,3308;-8457,3186;-8410,3066;-8352,2934;-8289,2806;-8220,2680;-8146,2558;-8066,2439;-7982,2324;-7892,2212;-7798,2104;-7699,2001;-7596,1902;-7488,1808;-7376,1718;-7261,1634;-7142,1554;-7020,1480;-6894,1411;-6766,1348;-6634,1290;-6514,1243;-6392,1200;-6268,1162;-6142,1127;-6015,1097;-5886,1070;-5756,1046;-5625,1026;-5493,1009;-5360,994;-5227,982;-5093,973;-4958,965;-4823,960;-4687,956;-4551,953;-4414,951;-4276,950;-4000,950;-4000,450);(-9000,-250;-9000,250;-4000,250;-4000,-250);(0,450;0,950;276,950;414,951;551,953;687,956;823,960;958,965;1093,973;1227,982;1360,994;1493,1009;1625,1026;1756,1046;1886,1070;2015,1097;2142,1127;2268,1162;2392,1200;2514,1243;2634,1290;2766,1348;2894,1411;3020,1480;3142,1554;3261,1634;3376,1718;3488,1808;3596,1902;3699,2001;3798,2104;3892,2212;3982,2324;4066,2439;4146,2558;4220,2680;4289,2806;4352,2934;4410,3066;4457,3186;4500,3308;4538,3432;4573,3558;4603,3685;4630,3814;4654,3944;4674,4075;4691,4207;4706,4340;4718,4473;4727,4607;4735,4742;4740,4877;4744,5013;4747,5149;4749,5286;4750,5424;4750,5700;5250,5700;5250,5422;5249,5282;5247,5141;5244,5001;5240,4859;5234,4718;5226,4576;5216,4433;5203,4290;5188,4147;5169,4004;5147,3861;5121,3718;5091,3576;5057,3433;5018,3292;4975,3151;4926,3012;4872,2874;4806,2723;4733,2575;4653,2430;4568,2289;4476,2152;4379,2019;4275,1891;4167,1767;4053,1647;3933,1533;3809,1425;3681,1321;3548,1224;3411,1132;3270,1047;3125,967;2977,894;2826,828;2688,774;2549,725;2408,682;2267,643;2124,609;1982,579;1839,553;1696,531;1553,512;1410,497;1267,484;1124,474;982,466;841,460;699,456;559,453;418,451;278,450);(0,-250;0,250;5000,250;5000,-250);(-4000,450;-4000,950;0,950;0,450);(-4000,-250;-4000,250;0,250;0,-250);(-12000,-250;-12000,250;-9000,250;-9000,-250);(5000,-250;5000,250;8000,250;8000,-250)
c2 = c.copy()
r = r.sized(2000)
c2.add_polygon(r, layer=LAYER.SLAB90)
c2
../_images/2b4b60dbccdbe779d8012a511866966edfa0b4e2f55d4bcacd0681d5c4515b78.png

To avoid acute angles you can run over / under (dilation+erosion).

c2 = c.copy()

d = 800
r = gf.kdb.Region(polygons)
r = r.sized(+d + 2000)
r = r.sized(-d)
c2.add_polygon(r, layer=LAYER.SLAB90)
c2
../_images/76eb5f07bdf3aa20c1cacd6af0c466011674f9b790763474d3b99bb2f8632ff3.png

Outline#

c2 = gf.Component()

d = 800
r = gf.kdb.Region(polygons)
r_sized = r.sized(+2000)

r_outline = r_sized - r
c2.add_polygon(r_outline, layer=LAYER.SLAB90)
c2
../_images/72ac45ef173d4ad2e73316830bb683ac42b79258639170ab449ac76dcf570051.png

Round corners#

c = gf.c.triangle()
c
../_images/e39eef60c2a5faddb0671c08013714505cb54e551722b62240992d7612e3d55e.png
c2 = gf.Component()

rinner = 1000  # 	The circle radius of inner corners (in database units).
router = 1000  # 	The circle radius of outer corners (in database units).
n = 300  # 	The number of points per full circle.

# round corners for one layer only
for p in c.get_polygons()[LAYER.WG]:
    p_round = p.round_corners(rinner, router, n)
    c2.add_polygon(p_round, layer=LAYER.WG)

c2
../_images/f8949d971ac7d18d1ab4ab2616ee63ecded664dc459feb066cba624b8bef2f03.png
c = gf.Component()
t = c << gf.c.triangle(x=10, y=20, layer="WG")
t = c << gf.c.triangle(x=20, y=40, layer="SLAB90")

c2 = gf.Component()
rinner = 1000  # 	The circle radius of inner corners (in database units).
router = 1000  # 	The circle radius of outer corners (in database units).
n = 300  # 	The number of points per full circle.

# round corners for all layers
for layer, polygons in c.get_polygons().items():
    for p in polygons:
        p_round = p.round_corners(rinner, router, n)
        c2.add_polygon(p_round, layer=layer)

c2
../_images/11f53df671de2cc5922f7f5e03eec93a1c286f9da08210ecda7a9dece38ab685.png

Union#

import gdsfactory as gf

c = gf.Component()
e0 = c << gf.components.ellipse(layer=(1, 0))
e1 = c << gf.components.ellipse(layer=(2, 0))
e2 = c << gf.components.ellipse(layer=(3, 0))
e3 = c << gf.components.ellipse(layer=(4, 0))
e4 = c << gf.components.ellipse(layer=(5, 0))
e5 = c << gf.components.ellipse(layer=(6, 0))

e1.drotate(15 * 1)
e2.drotate(15 * 2)
e3.drotate(15 * 3)
e4.drotate(15 * 4)
e5.drotate(15 * 5)

c
../_images/377c0a2cdd9e13256b5d33ca9c2b66460965c5193f3d0210d0c94ab6894fa169.png
polygons = c.get_polygons()
r = gf.kdb.Region()

for polys in polygons.values():
    r = r + gf.kdb.Region(polys)

c2 = gf.Component()
c2.add_polygon(r, layer=(1, 0))
c2
../_images/9b4f3cd2a4c3acd98e84282ff0a9a46597c78695809d035c13694ae3b5bbdbfa.png

Importing GDS files#

gf.import_gds() allows you to easily import external GDSII files. It imports a single cell from the external GDS file and converts it into a gdsfactory component.

D = gf.components.ellipse()
D.write_gds("myoutput.gds")
D2 = gf.import_gds(gdspath="myoutput.gds")
D2.plot()
../_images/a564cb2aa6a42d34dfd08acd479c9ffbec1633cace43f72a88c09871f88bff75.png

Copying and extracting geometry#

E = gf.Component()
E.add_ref(gf.components.ellipse(layer=(1, 0)))
D = E.extract(layers=[(1, 0)])
D.plot()
../_images/a564cb2aa6a42d34dfd08acd479c9ffbec1633cace43f72a88c09871f88bff75.png
import gdsfactory as gf

X = gf.components.ellipse(layer=(2, 0))
c = X.copy()
c.plot()
../_images/f82d22c0e7ad357295724e166943c645a2dd38655c1a85a71105bc70fd5bcc17.png
c_copied_layers = gf.components.copy_layers(
    gf.components.straight, layers=((1, 0), (2, 0))
)
c_copied_layers.plot()
../_images/dda5cf4789fff3432f30cf073409d04f72e278fce9eb2a3712bb36d04f0886cc.png

Import Images into GDS#

You can import your logo into GDS using the conversion from numpy arrays.

from gdsfactory.config import PATH
from gdsfactory.read.from_np import from_image
import gdsfactory as gf

c = from_image(
    PATH.module / "samples" / "images" / "logo.png", nm_per_pixel=500, invert=False
)
c.plot()
../_images/e72d76bedcd2f952237d2535f7b181ae8635347dccf2738968fa428e3307c682.png
c = from_image(
    PATH.module / "samples" / "images" / "logo.png", nm_per_pixel=500, invert=True
)
c.plot()
../_images/61982c2de66ad457442dd79c6e1874db1e7389d767baa48a63569062f091fc78.png

Dummy Fill / Tiling#

To keep constant density in some layers you can add dummy fill shapes.

Custom fill cell#

You can use a custom cell as a fill.

Tiling processor#

For big layouts you can should use klayout tiling processor.

import kfactory as kf

import gdsfactory as gf
from kfactory.utils.fill import fill_tiled

c = kf.KCell("ToFill")
c.shapes(kf.kcl.layer(1, 0)).insert(
    kf.kdb.DPolygon.ellipse(kf.kdb.DBox(5000, 3000), 512)
)
c.shapes(kf.kcl.layer(10, 0)).insert(
    kf.kdb.DPolygon(
        [kf.kdb.DPoint(0, 0), kf.kdb.DPoint(5000, 0), kf.kdb.DPoint(5000, 3000)]
    )
)

fc = kf.KCell()
fc.shapes(fc.kcl.layer(2, 0)).insert(kf.kdb.DBox(20, 40))
fc.shapes(fc.kcl.layer(3, 0)).insert(kf.kdb.DBox(30, 15))

# fill.fill_tiled(c, fc, [(kf.kcl.layer(1,0), 0)], exclude_layers = [(kf.kcl.layer(10,0), 100), (kf.kcl.layer(2,0), 0), (kf.kcl.layer(3,0),0)], x_space=5, y_space=5)
fill_tiled(
    c,
    fc,
    [(kf.kcl.layer(1, 0), 0)],
    exclude_layers=[
        (kf.kcl.layer(10, 0), 100),
        (kf.kcl.layer(2, 0), 0),
        (kf.kcl.layer(3, 0), 0),
    ],
    x_space=5,
    y_space=5,
)

gdspath = "mzi_fill.gds"
c.write(gdspath)
c = gf.import_gds(gdspath, cellname="ToFill")
c.plot()
../_images/8203714ea8d80728248f16a010e1605326052cbf0ea268e727937e52b0ded653.png