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

Improve layer stack #2726

Merged
merged 7 commits into from
May 9, 2024
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions gdsfactory/components/straight_heater_metal.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,36 +242,39 @@ def straight_heater_metal_simple(
straight_heater_metal = partial(
straight_heater_metal_undercut,
with_undercut=False,
length_straight_input=0.1,
length_undercut=5,
length_undercut_spacing=0,
)
straight_heater_metal_90_90 = partial(
straight_heater_metal_undercut,
straight_heater_metal,
with_undercut=False,
port_orientation1=90,
port_orientation2=90,
)
straight_heater_metal_undercut_90_90 = partial(
straight_heater_metal_undercut,
straight_heater_metal,
with_undercut=False,
port_orientation1=90,
port_orientation2=90,
)


def test_ports() -> None:
c = straight_heater_metal(length=100.0)
assert c.ports["o2"].center[0] == 100.0, c.ports["o2"].center[0]
c = straight_heater_metal(length=30.0)
assert c.ports["o2"].center[0] == 30.0, c.ports["o2"].center[0]


if __name__ == "__main__":
test_ports()
# test_ports()
# c = straight_heater_metal_undercut()
# print(c.ports['o2'].center[0])
# c.pprint_ports()
# c = straight_heater_metal(heater_width=5, length=50.0)

# c = straight_heater_metal_undercut(length=200, straight="straight")
# n = c.get_netlist()
c = straight_heater_metal(length=80)
c = straight_heater_metal(length=30)
# print(c.get_netlist(allow_multiple=True))
# c = straight_heater_metal_simple(length=20)
c.show(show_ports=False)
Expand Down
31 changes: 14 additions & 17 deletions gdsfactory/export/to_3d.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,26 +37,23 @@ def to_3d(
layer_stack = layer_stack or get_layer_stack()

scene = Scene()
layer_to_thickness = layer_stack.get_layer_to_thickness()
layer_to_zmin = layer_stack.get_layer_to_zmin()
exclude_layers = exclude_layers or ()
# layers = layer_views.layer_map.values()

component_with_booleans = layer_stack.get_component_with_derived_layers(component)
component_layers = component_with_booleans.get_layers()
has_polygons = False

for layer, polygons in component_with_booleans.get_polygons(
layer_to_polygon = component_with_booleans.get_polygons(
by_spec=True, as_array=False
).items():
if (
layer not in exclude_layers
and layer in layer_to_zmin
and layer in layer_to_thickness
and layer in component_layers
):
height = layer_to_thickness[layer]
zmin = layer_to_zmin[layer]
)

for level in layer_stack.layers.values():
layer = level.layer

if layer not in exclude_layers and layer in component_layers:
height = level.thickness
zmin = level.zmin
layer_view = layer_views.get_from_tuple(layer)
color_rgb = [
c / 255 for c in layer_view.fill_color.as_rgb_tuple(alpha=False)
Expand All @@ -65,7 +62,7 @@ def to_3d(
# print(layer, height, zmin, opacity, layer_view.visible)

if zmin is not None and layer_view.visible:
for polygon in polygons:
for polygon in layer_to_polygon[layer]:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (edge_case_not_handled): Check if 'layer_to_polygon' dictionary always contains all layers as keys to avoid KeyError.

p = shapely.geometry.Polygon(polygon.points)
mesh = extrude_polygon(p, height=height)
mesh.apply_translation((0, 0, zmin))
Expand All @@ -88,9 +85,9 @@ def to_3d(
# c = gf.Component()
# c << gf.components.straight_heater_metal(length=40)
# c << gf.c.rectangle(layer=(113, 0))
c = gf.components.grating_coupler_elliptical_trenches()
# c = gf.components.grating_coupler_elliptical_trenches()
# c = gf.components.taper_strip_to_ridge_trenches()

c = gf.c.straight_heater_metal(length=20)
c.show()
# s = c.to_3d()
# s.show()
s = c.to_3d()
s.show()
82 changes: 39 additions & 43 deletions gdsfactory/export/to_stl.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@

layer_stack = layer_stack or get_layer_stack()

layer_to_thickness = layer_stack.get_layer_to_thickness()
layer_to_zmin = layer_stack.get_layer_to_zmin()
filepath = pathlib.Path(filepath)
exclude_layers = exclude_layers or []

Expand All @@ -46,47 +44,45 @@
layer_names = list(layer_stack.layers.keys())
layer_tuples = list(layer_stack.layers.values())

for layer, polygons in component_with_booleans.get_polygons(by_spec=True).items():
if (
layer in exclude_layers
or layer not in layer_to_thickness
or layer not in layer_to_zmin
or layer not in component_layers
):
continue

height = layer_to_thickness[layer]
zmin = layer_to_zmin[layer]

layer_name = (
layer_names[layer_tuples.index(layer)]
if use_layer_name
else f"{layer[0]}_{layer[1]}"
)

filepath_layer = (
filepath.parent / f"{filepath.stem}_{layer_name}{filepath.suffix}"
)
print(
f"Write {filepath_layer.absolute()!r} zmin = {zmin:.3f}, height = {height:.3f}"
)
meshes = []
for polygon in polygons:
p = shapely.geometry.Polygon(polygon)

if hull_invalid_polygons and not p.is_valid:
p = p.convex_hull

mesh = trimesh.creation.extrude_polygon(p, height=height)
mesh.apply_translation((0, 0, zmin))
meshes.append(mesh)

layer_mesh = trimesh.util.concatenate(meshes)

if scale:
layer_mesh.apply_scale(scale)

layer_mesh.export(filepath_layer)
layer_to_polygons = component_with_booleans.get_polygons(by_spec=True)

for level in layer_stack.layers.values():
layer = level.layer

if layer not in exclude_layers and layer in component_layers:
height = level.thickness
zmin = level.zmin

layer_name = (
layer_names[layer_tuples.index(layer)]
if use_layer_name
else f"{layer[0]}_{layer[1]}"
)

filepath_layer = (
filepath.parent / f"{filepath.stem}_{layer_name}{filepath.suffix}"
)
print(
f"Write {filepath_layer.absolute()!r} zmin = {zmin:.3f}, height = {height:.3f}"
)
meshes = []
polygons = layer_to_polygons[layer]
for polygon in polygons:
p = shapely.geometry.Polygon(polygon)

if hull_invalid_polygons and not p.is_valid:
p = p.convex_hull

Check warning on line 74 in gdsfactory/export/to_stl.py

View check run for this annotation

Codecov / codecov/patch

gdsfactory/export/to_stl.py#L74

Added line #L74 was not covered by tests

mesh = trimesh.creation.extrude_polygon(p, height=height)
mesh.apply_translation((0, 0, zmin))
meshes.append(mesh)

layer_mesh = trimesh.util.concatenate(meshes)

if scale:
layer_mesh.apply_scale(scale)

layer_mesh.export(filepath_layer)


if __name__ == "__main__":
Expand Down
19 changes: 7 additions & 12 deletions gdsfactory/export/to_svg.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@
layer_views = layer_views or get_layer_views()
layer_stack = layer_stack or get_layer_stack()

layer_to_thickness = layer_stack.get_layer_to_thickness()
layer_to_zmin = layer_stack.get_layer_to_zmin()
exclude_layers = exclude_layers or ()
# layers = layer_views.layer_map.values()

Expand All @@ -41,6 +39,7 @@
dcx, dcy = component.center
dx, dy = dcx - xsize / 2, dcy - ysize / 2
group_num = 1
layer_to_polygons = component_with_booleans.get_polygons(by_spec=True)

Check warning on line 42 in gdsfactory/export/to_svg.py

View check run for this annotation

Codecov / codecov/patch

gdsfactory/export/to_svg.py#L42

Added line #L42 was not covered by tests

with open(filename, "w+") as f:
f.write('<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n')
Expand All @@ -51,20 +50,16 @@
' xmlns="http://www.w3.org/2000/svg">\n'
)

for layer, polygons in component_with_booleans.get_polygons(
by_spec=True, as_array=True
).items():
if (
layer not in exclude_layers
and layer in layer_to_zmin
and layer in layer_to_thickness
and layer in component_layers
):
zmin = layer_to_zmin[layer]
for level in layer_stack.layers.values():
layer = level.layer

Check warning on line 54 in gdsfactory/export/to_svg.py

View check run for this annotation

Codecov / codecov/patch

gdsfactory/export/to_svg.py#L54

Added line #L54 was not covered by tests

if layer not in exclude_layers and layer in component_layers:
zmin = level.zmin

Check warning on line 57 in gdsfactory/export/to_svg.py

View check run for this annotation

Codecov / codecov/patch

gdsfactory/export/to_svg.py#L57

Added line #L57 was not covered by tests
layer_view = layer_views.get_from_tuple(layer)
color = layer_view.fill_color.as_hex(format="short")
f.write(' <g id="layer%03i_datatype%03i">\n' % (layer[0], layer[1]))
group_num += 1
polygons = layer_to_polygons[layer]

Check warning on line 62 in gdsfactory/export/to_svg.py

View check run for this annotation

Codecov / codecov/patch

gdsfactory/export/to_svg.py#L62

Added line #L62 was not covered by tests

if zmin is not None and layer_view.visible:
for polygon in polygons:
Expand Down
42 changes: 38 additions & 4 deletions gdsfactory/technology/layer_stack.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

import gdstk
from pydantic import BaseModel, Field
from rich.console import Console
from rich.table import Table

import gdsfactory as gf
from gdsfactory.cell import cell
Expand Down Expand Up @@ -94,6 +96,21 @@
"""Returns a copy of the LayerStack."""
return LayerStack.model_validate_json(self.model_dump_json())

def pprint(self) -> None:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (code_refinement): Consider renaming 'pprint' to a more descriptive method name indicating its specific functionality.

Suggested change
def pprint(self) -> None:
def print_layer_stack_table(self) -> None:

console = Console()
table = Table(show_header=True, header_style="bold")
keys = ["layer", "thickness", "material", "sidewall_angle"]

Check warning on line 102 in gdsfactory/technology/layer_stack.py

View check run for this annotation

Codecov / codecov/patch

gdsfactory/technology/layer_stack.py#L100-L102

Added lines #L100 - L102 were not covered by tests

for key in ["name"] + keys:
table.add_column(key)

Check warning on line 105 in gdsfactory/technology/layer_stack.py

View check run for this annotation

Codecov / codecov/patch

gdsfactory/technology/layer_stack.py#L105

Added line #L105 was not covered by tests

for layer_name, layer in self.layers.items():
port_dict = dict(layer)

Check warning on line 108 in gdsfactory/technology/layer_stack.py

View check run for this annotation

Codecov / codecov/patch

gdsfactory/technology/layer_stack.py#L108

Added line #L108 was not covered by tests
row = [layer_name] + [str(port_dict.get(key, "")) for key in keys]
table.add_row(*row)

Check warning on line 110 in gdsfactory/technology/layer_stack.py

View check run for this annotation

Codecov / codecov/patch

gdsfactory/technology/layer_stack.py#L110

Added line #L110 was not covered by tests

console.print(table)

Check warning on line 112 in gdsfactory/technology/layer_stack.py

View check run for this annotation

Codecov / codecov/patch

gdsfactory/technology/layer_stack.py#L112

Added line #L112 was not covered by tests

def __init__(self, **data: Any) -> None:
"""Add LayerLevels automatically for subclassed LayerStacks."""
super().__init__(**data)
Expand Down Expand Up @@ -399,7 +416,21 @@
for layer_name in unetched_layers
if layer_stack.layers[layer_name].layer in component_layers
]
component_derived = component.extract(unetched_layer_numbers)
layer_to_polygons = component.get_polygons(by_spec=True)

# component_derived = component.extract(unetched_layer_numbers)
component_derived = gf.Component()

for layer in unetched_layer_numbers:
polygons = layer_to_polygons[layer]
unetched_polys = gdstk.boolean(
operand1=polygons,
operand2=[],
operation="or",
layer=layer[0],
datatype=layer[1],
)
component_derived.add(unetched_polys)

# Define unetched layers
polygons_to_remove = []
Expand Down Expand Up @@ -432,7 +463,6 @@

# Remove all etching layers
layer = layer_stack.layers[unetched_layer_name].layer
polygons = component.get_polygons(by_spec=layer)
unetched_polys = gdstk.boolean(
operand1=polygons,
operand2=polygons_to_remove,
Expand All @@ -453,11 +483,15 @@

from gdsfactory.generic_tech import LAYER_STACK

layer_stack = LAYER_STACK
ls = LAYER_STACK
# ls.pprint()

c = gf.components.straight_heater_metal()
c = gf.components.straight_heater_metal(length=30)
c.show()

s = c.to_3d()
s.show()

# import gdsfactory as gf
# from gdsfactory.generic_tech import LAYER_STACK
# component = c = gf.components.grating_coupler_elliptical_trenches()
Expand Down
6 changes: 6 additions & 0 deletions test-data-regression/test_settings_mzi_pads_center_.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,15 @@ settings:
function: straight_heater_metal_undercut
module: gdsfactory.components.straight_heater_metal
settings:
length_straight_input: 0.1
length_undercut: 5
length_undercut_spacing: 0
with_undercut: false
ps_top:
function: straight_heater_metal_undercut
module: gdsfactory.components.straight_heater_metal
settings:
length_straight_input: 0.1
length_undercut: 5
length_undercut_spacing: 0
with_undercut: false
8 changes: 4 additions & 4 deletions test-data-regression/test_settings_straight_heater_metal_.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ function: straight_heater_metal_undercut
info:
resistance: 0
module: gdsfactory.components.straight_heater_metal
name: straight_heater_metal_undercut_with_undercutFalse
name: straight_heater_metal_undercut_539ff9ab
settings:
cross_section: xs_sc
cross_section_heater: xs_heater_metal
Expand All @@ -11,9 +11,9 @@ settings:
heater_taper_length: 5.0
length: 320.0
length_straight: 0.1
length_straight_input: 15.0
length_undercut: 30.0
length_undercut_spacing: 6.0
length_straight_input: 0.1
length_undercut: 5
length_undercut_spacing: 0
ohms_per_square: null
port_orientation1: null
port_orientation2: null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ function: straight_heater_metal_undercut
info:
resistance: 0
module: gdsfactory.components.straight_heater_metal
name: straight_heater_metal_undercut_47ed7538
name: straight_heater_metal_undercut_68a15837
settings:
cross_section: xs_sc
cross_section_heater: xs_heater_metal
Expand All @@ -11,9 +11,9 @@ settings:
heater_taper_length: 5.0
length: 320.0
length_straight: 0.1
length_straight_input: 15.0
length_undercut: 30.0
length_undercut_spacing: 6.0
length_straight_input: 0.1
length_undercut: 5
length_undercut_spacing: 0
ohms_per_square: null
port_orientation1: 90
port_orientation2: 90
Expand Down
Loading
Loading