Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add shapely polygons #1634

Merged
merged 2 commits into from May 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
82 changes: 73 additions & 9 deletions docs/notebooks/00_geometry.py
Expand Up @@ -23,7 +23,9 @@
# In gdsfactory **all dimensions** are in **microns**

# %% [markdown]
# Lets add a polygon
# ## Polygons
#
# You can add polygons to different layers.

# %% tags=[]
import gdsfactory as gf
Expand All @@ -49,7 +51,7 @@
# %% [markdown]
# **Exercise** :
#
# Make a component similar to the one above that has a second polygon in layer (1, 1)
# Make a component similar to the one above that has a second polygon in layer (2, 0)

# %% tags=[]
c = gf.Component("myComponent2")
Expand All @@ -73,12 +75,77 @@
print(c)
c

# %% [markdown]
# You define polygons both from `gdstk` or `Shapely`

# %%
from shapely.geometry.polygon import Polygon
import gdstk
import gdsfactory as gf

c = gf.Component("Mixed_polygons")
p0 = Polygon(zip((-8, 6, 7, 9), (-6, 8, 17, 5)))
p1 = p0.buffer(1)
p2 = p1.simplify(tolerance=0.1)
c.add_polygon(p0, layer=0)
c.add_polygon(p1, layer=1)
c.add_polygon(p2, layer=2)

c.add_polygon([(-8, 6, 7, 9), (-6, 8, 17, 5)], layer=3)
c

# %%
p0

# %%
p1 = p0.buffer(1)
p1

# %%
pnot = p1 - p0
pnot

# %%
c = gf.Component("exterior")
c.add_polygon(pnot, layer=3)
c

# %%
p_small = p0.buffer(-1)
p_small

# %%
p_or = pnot | p_small
p_or

# %%
c = gf.Component("p_or")
c.add_polygon(p_or, layer=1)
c

# %%
import shapely as sp

p5 = sp.envelope(p0)
p5

# %%
p6 = p5 - p0
p6

# %%
c = gf.Component("p6")
c.add_polygon(p6, layer=1)
c

# %% [markdown]
# ## Connect **ports**
#
# Components can have a "Port" that allows you to connect ComponentReferences together like legos.
#
# You can write a simple function to make a rectangular straight, assign ports to the ends, and then connect those rectangles together.
#
# Notice that `connect` transform each reference but things won't remain connected if you move any of the references afterwards.


# %%
Expand Down Expand Up @@ -178,7 +245,7 @@ def straight(length=10, width=1, layer=(1, 0)):
# %% [markdown]
# ## References
#
# Now that we have your component `c` is a multi-straight component, you can add references to that component in a new blank Component `c2`, then add two references and shift one to see the movement.
# Now that your component `c` is a multi-straight component, you can add references to that component in a new blank Component `c2`, then add two references and shift one to see the movement.

# %%
c2 = gf.Component("MultiMultiWaveguide")
Expand All @@ -197,24 +264,21 @@ def straight(length=10, width=1, layer=(1, 0)):
# %% [markdown]
# ## Labels
#
# You can add abstract GDS labels (annotate) to your Components, in order to record information
# You can add abstract GDS labels to annotate your Components, in order to record information
# directly into the final GDS file without putting any extra geometry onto any layer
# This label will display in a GDS viewer, but will not be rendered or printed
# like the polygons created by gf.components.text().
# like the polygons created by `gf.components.text()`.

# %%
c2.add_label(text="First label", position=mwg1_ref.center)
c2.add_label(text="Second label", position=mwg2_ref.center)

# It's very useful for recording information about the devices or layout
# labels are useful for recording information
c2.add_label(
text=f"The x size of this\nlayout is {c2.xsize}",
position=(c2.xmax, c2.ymax),
layer=(10, 0),
)

# Again, note we have to write the GDS for it to be visible (view in KLayout)
c2.write_gds("MultiMultiWaveguideWithLabels.gds")
c2

# %% [markdown]
Expand Down
39 changes: 37 additions & 2 deletions gdsfactory/component.py
Expand Up @@ -1005,6 +1005,36 @@
self._add_polygons(polygon)
return polygon

elif hasattr(points, "geoms"):
for geom in points.geoms:
polygon = self.add_polygon(geom, layer=layer)
return polygon

Check warning on line 1011 in gdsfactory/component.py

View check run for this annotation

Codecov / codecov/patch

gdsfactory/component.py#L1010-L1011

Added lines #L1010 - L1011 were not covered by tests
elif hasattr(points, "exterior"): # points is a shapely Polygon
layer, datatype = _parse_layer(layer)
points_on_grid = np.round(points.exterior.coords, 3)
polygon = gdstk.Polygon(points_on_grid, layer, datatype)

Check warning on line 1015 in gdsfactory/component.py

View check run for this annotation

Codecov / codecov/patch

gdsfactory/component.py#L1013-L1015

Added lines #L1013 - L1015 were not covered by tests

if points.interiors:
from shapely import get_coordinates

Check warning on line 1018 in gdsfactory/component.py

View check run for this annotation

Codecov / codecov/patch

gdsfactory/component.py#L1018

Added line #L1018 was not covered by tests

points_on_grid_interior = np.round(get_coordinates(points.interiors), 3)
polygon_interior = gdstk.Polygon(

Check warning on line 1021 in gdsfactory/component.py

View check run for this annotation

Codecov / codecov/patch

gdsfactory/component.py#L1020-L1021

Added lines #L1020 - L1021 were not covered by tests
points_on_grid_interior, layer, datatype
)
polygons = gdstk.boolean(

Check warning on line 1024 in gdsfactory/component.py

View check run for this annotation

Codecov / codecov/patch

gdsfactory/component.py#L1024

Added line #L1024 was not covered by tests
polygon,
polygon_interior,
operation="not",
layer=layer,
datatype=datatype,
)
for polygon in polygons:
self._add_polygons(polygon)
return polygon

Check warning on line 1033 in gdsfactory/component.py

View check run for this annotation

Codecov / codecov/patch

gdsfactory/component.py#L1032-L1033

Added lines #L1032 - L1033 were not covered by tests

self._add_polygons(polygon)
return polygon

Check warning on line 1036 in gdsfactory/component.py

View check run for this annotation

Codecov / codecov/patch

gdsfactory/component.py#L1035-L1036

Added lines #L1035 - L1036 were not covered by tests

points = np.asarray(points)
if points.ndim == 1:
return [self.add_polygon(poly, layer=layer) for poly in points]
Expand Down Expand Up @@ -2815,9 +2845,14 @@
if __name__ == "__main__":
import gdsfactory as gf

c = gf.Component()
p = c.add_polygon(
[(-8, 6, 7, 9), (-6, 8, 17, 5)], layer=(1, 0)
) # GDS layers are tuples of ints (but if we use only one number it assumes the other number is 0)

# c2 = gf.Component()
c = gf.components.mzi()
print(c.get_layer_names())
# c = gf.components.mzi()
# print(c.get_layer_names())
# r = c.ref()
# c2.copy_child_info(c.named_references["sxt"])
# test_remap_layers()
Expand Down
@@ -1,4 +1,4 @@
# Globalfoundries GENERIC TECH LVS Tests
# GENERIC TECH LVS Tests


## Folder Structure
Expand Down
Expand Up @@ -79,4 +79,5 @@ def heater_lvs() -> gf.Component:

if __name__ == "__main__":
c = heater_lvs()
c.write_gds("straight_heater_metal.gds")
c.show()