Skip to content

Commit

Permalink
Merge pull request #2726 from gdsfactory/improve_layer_stack
Browse files Browse the repository at this point in the history
Improve layer stack
  • Loading branch information
joamatab committed May 9, 2024
2 parents d55a056 + 614af21 commit 141cd3d
Show file tree
Hide file tree
Showing 10 changed files with 129 additions and 95 deletions.
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]:
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 @@ def to_stl(

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 @@ def to_stl(
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

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 @@ def to_svg(
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 @@ def to_svg(
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)

with open(filename, "w+") as f:
f.write('<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n')
Expand All @@ -51,20 +50,16 @@ def to_svg(
' 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

if layer not in exclude_layers and layer in component_layers:
zmin = level.zmin
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]

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 @@ def model_copy(self) -> LayerStack:
"""Returns a copy of the LayerStack."""
return LayerStack.model_validate_json(self.model_dump_json())

def pprint(self) -> None:
console = Console()
table = Table(show_header=True, header_style="bold")
keys = ["layer", "thickness", "material", "sidewall_angle"]

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

for layer_name, layer in self.layers.items():
port_dict = dict(layer)
row = [layer_name] + [str(port_dict.get(key, "")) for key in keys]
table.add_row(*row)

console.print(table)

def __init__(self, **data: Any) -> None:
"""Add LayerLevels automatically for subclassed LayerStacks."""
super().__init__(**data)
Expand Down Expand Up @@ -399,7 +416,21 @@ def get_component_with_derived_layers(component, layer_stack: LayerStack) -> Com
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 @@ def get_component_with_derived_layers(component, layer_stack: LayerStack) -> Com

# 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 @@ def get_component_with_derived_layers(component, layer_stack: LayerStack) -> Com

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

0 comments on commit 141cd3d

Please sign in to comment.