From 700cf9af397e8ec6be34234284b33418d6fe4c25 Mon Sep 17 00:00:00 2001 From: Helge Gehring Date: Tue, 2 Mar 2021 12:40:03 +0100 Subject: [PATCH] GDSII-export now also supports LineStrings --- gdshelpers/export/gdsii_export.py | 36 +++++++++++++++++++------------ 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/gdshelpers/export/gdsii_export.py b/gdshelpers/export/gdsii_export.py index 15e0ea5..dd24058 100644 --- a/gdshelpers/export/gdsii_export.py +++ b/gdshelpers/export/gdsii_export.py @@ -9,7 +9,7 @@ from io import BytesIO import numpy as np -from shapely.geometry import Polygon +from shapely.geometry import Polygon, LineString def _real_to_8byte(value): @@ -28,25 +28,31 @@ def _cell_to_gdsii_binary(cell, grid_steps_per_unit, max_points, max_line_points b.write(pack('>2H', 4 + len(name), 0x0606) + name.encode('ascii')) # STRNAME STRING cell_name for layer, polygons in cell.get_fractured_layer_dict(max_points, max_line_points).items(): - for polygon in polygons: - if not isinstance(polygon, Polygon): + for shapely_object in polygons: + if isinstance(shapely_object, Polygon): + if shapely_object.interiors: + raise AssertionError('GDSII only supports polygons without holes') + coords = list(shapely_object.exterior.coords) + [shapely_object.exterior.coords[0]] + b.write(pack('>8H', 4, 0x0800, # BOUNDARY NO_DATA + 6, 0x0D02, layer, # LAYER INTEGER_2 layer + 6, 0x0E02, layer)) # DATATYPE INTEGER_2 datatype + elif isinstance(shapely_object, LineString): + coords = shapely_object.coords + b.write(pack('>8H', 4, 0x0900, # PATH NO_DATA + 6, 0x0D02, layer, # LAYER INTEGER_2 layer + 6, 0x0E02, layer)) # DATATYPE INTEGER_2 datatype + else: import warnings warnings.warn( - 'Shapely object of type ' + str(type(polygon)) + ' not convertible to GDSII, skipping...') + 'Shapely object of type ' + str( + type(shapely_object)) + ' not convertible to GDSII, skipping...') continue - if polygon.interiors: - raise AssertionError('GDSII only supports polygons without holes') - xy = np.round( - np.array( - list(polygon.exterior.coords) + [polygon.exterior.coords[0]]) * grid_steps_per_unit).astype( - '>i4') - b.write(pack('>8H', 4, 0x0800, # BOUNDARY NO_DATA - 6, 0x0D02, layer, # LAYER INTEGER_2 layer - 6, 0x0E02, layer)) # DATATYPE INTEGER_2 datatype + + xy = np.round(np.array(coords) * grid_steps_per_unit).astype('>i4') for start in range(0, xy.shape[0], 8191): # Split in Blocks of 8191 points stop = min(start + 8191, xy.shape[0]) b.write(pack('>2H', 4 + 8 * (stop - start), 0x1003)) # XY INTEGER_4 - b.write(xy[start:stop].tobytes()) # coords of polygon + b.write(xy[start:stop].tobytes()) # coords of shapely_object b.write(pack('>2H', 4, 0x1100)) # ENDEL NO_DATA for ref in cell.cells: @@ -141,6 +147,8 @@ def add_cells_to_unique_list(start_cell): sub_cell = Cell('sub_cell') sub_cell.add_to_layer(1, waveguide) + sub_cell.add_to_layer(3, LineString(((0, 0), (100, 100)))) + device_cell.add_cell(sub_cell, origin=(10, 10), angle=np.pi / 2) with open('gdsii_export.gds', 'wb') as file: