### Install Gdstk using pip or from source Source: https://context7.com/heitzmann/gdstk/llms.txt Install the Gdstk library using pip for quick setup or build from source for advanced customization. Building from source requires CMake and Ninja. ```sh # From PyPI pip install gdstk # From source (requires CMake + Ninja) pip install build python -m build -w pip install dist/gdstk-*.whl ``` -------------------------------- ### Install C++ Library with CMake Source: https://github.com/heitzmann/gdstk/blob/main/README.md Installs the C++ library using CMake. Ensure zlib and qhull are installed. Use -DCMAKE_INSTALL_PREFIX to set the installation path. ```sh cmake -S . -B build cmake --build build --target install ``` -------------------------------- ### Define and Build C++ gdstk Examples Source: https://github.com/heitzmann/gdstk/blob/main/docs/cpp/CMakeLists.txt This CMake script configures the build process for multiple C++ examples. It iterates through a list of example names, creates an executable for each, ensures C++11 compatibility, links the gdstk library, and adds each executable as a test. ```cmake set(ALL_EXAMPLES apply_repetition first flexpaths geometry_operations merging pads path_markers pcell photonics polygons pos_filtering references repetitions robustpaths text transforms layout filtering) foreach(EXAMPLE ${ALL_EXAMPLES}) add_executable(${EXAMPLE} EXCLUDE_FROM_ALL "${EXAMPLE}.cpp") target_compile_features(${EXAMPLE} PRIVATE cxx_std_11) target_link_libraries(${EXAMPLE} PRIVATE gdstk) add_test(NAME ${EXAMPLE} COMMAND ${EXAMPLE}) endforeach() add_custom_target(examples DEPENDS ${ALL_EXAMPLES}) ``` -------------------------------- ### Install pkg-config File Source: https://github.com/heitzmann/gdstk/blob/main/src/CMakeLists.txt Installs the generated pkg-config file to the appropriate location for the system's package manager to find it. ```cmake install(FILES "${CMAKE_CURRENT_BINARY_DIR}/gdstk.pc" DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) ``` -------------------------------- ### Install Python Wrapper from PyPI Source: https://github.com/heitzmann/gdstk/blob/main/README.md Installs the GDSTK Python module using pip. This command installs the package for the current user. ```sh pip install --user gdstk ``` -------------------------------- ### Create References in Python Source: https://github.com/heitzmann/gdstk/blob/main/docs/gettingstarted.rst Example of creating single and array references using gdstk.Reference in Python. Requires 'tutorial_images.py'. ```python import gdstk import math lib = gdstk.Library() # cell, polygons cell = lib.new_cell('DEMO') # References ref_cell = lib.new_cell('REF_CELL') ref_cell.add(gdstk.rectangle(0, 1, 0, 1)) # Single reference ref1 = gdstk.Reference(ref_cell, position=(10, 0), rotation=math.pi/4, scale=2) cell.add(ref1) # Array reference ref2 = gdstk.Reference(ref_cell, columns=3, row_spacing=5, column_spacing=5, origin=(0, 10)) cell.add(ref2) lib.write_gds('tutorial_images.gds') ``` -------------------------------- ### Create a GDSII/OASIS Library Instance (C++) Source: https://github.com/heitzmann/gdstk/blob/main/docs/gettingstarted.rst This C++ snippet demonstrates creating a `gdstk::Library` instance, analogous to the Python example, for managing GDSII/OASIS file data. ```c++ #include int main() { gdstk::Library lib("MyLibrary", 1e-6, 1e-9); return 0; } ``` -------------------------------- ### Define Parametric Cell in C++ Source: https://github.com/heitzmann/gdstk/blob/main/docs/how-tos.rst Illustrates the creation of a parametric cell using C++. This example demonstrates how to define reusable components with customizable parameters. ```c++ #include #include gdstk::Cell* grating(double period, double width, int num_periods, int layer=0, int datatype=0) { std::vector> pts; for (int i = 0; i < num_periods; ++i) { pts.push_back({{ {i * period}, 0.0 }, {i * period + width}, 0.0 }, {i * period + width}, 1.0 }, {i * period}, 1.0}}); } gdstk::Cell* cell = new gdstk::Cell("GRATING"); cell->add(new gdstk::Polygon(pts, layer, datatype)); return cell; } ``` -------------------------------- ### Install Python Extension Target Source: https://github.com/heitzmann/gdstk/blob/main/python/CMakeLists.txt Installs the built Python extension target to a specified component and destination directory. This makes the module available for import in Python. ```cmake install(TARGETS _gdstk COMPONENT _gdstk DESTINATION ${SKBUILD_PROJECT_NAME}) ``` -------------------------------- ### Use a Library in C++ Source: https://github.com/heitzmann/gdstk/blob/main/docs/how-tos.rst Illustrates the process of incorporating a GDSII library into a C++ layout design. This example shows how to load and reference cells from an external library. ```c++ #include #include int main() { gdstk::Library lib = gdstk::read_rawcells("photonics.gds"); gdstk::Cell* layout = new gdstk::Cell("LAYOUT"); // Add components from the library gdstk::Cell* coupler_cell = lib.cells.at("DIRECTIONAL_COUPLER"); layout->add(new gdstk::Reference(coupler_cell, {0.0, 0.0})); gdstk::Cell* mzi_cell = lib.cells.at("MACH_ZEHNDER_INTERFEROMETER"); layout->add(new gdstk::Reference(mzi_cell, {5.0, 0.0})); // Create a new library and write the layout gdstk::Library new_lib("layout_example"); new_lib.add(layout); new_lib.write_gds("layout_example.gds"); return 0; } ``` -------------------------------- ### Apply Transformations in C++ Source: https://github.com/heitzmann/gdstk/blob/main/docs/how-tos.rst Demonstrates geometric transformations on cells and geometries within a C++ GDSII layout. This example shows how to apply translations, rotations, and scaling using References. ```c++ #include #include int main() { // Create a simple cell gdstk::Cell* cell = new gdstk::Cell("TRANSFORM_EXAMPLE"); cell->add(new gdstk::Polygon({{ {0.0}, {0.0} }, { {1.0}, {0.0} }, { {1.0}, {1.0} }, { {0.0}, {1.0} }} )); cell->add(new gdstk::FlexPath({{ {0.0}, {2.0} }, { {1.0}, {2.0} }, { {1.0}, {3.0} }} ), 0.1, 1); // Create a library and add the cell gdstk::Library lib("transforms"); lib.add(cell); // Create transformed copies using Reference gdstk::Reference* ref_translated = new gdstk::Reference(cell, {3.0, 0.0}); gdstk::Reference* ref_rotated = new gdstk::Reference(cell, {0.0, 3.0}, 45.0); gdstk::Reference* ref_scaled = new gdstk::Reference(cell, {3.0, 3.0}, 0.0, 0.5); // Create a new cell to hold the references gdstk::Cell* main_cell = new gdstk::Cell("MAIN"); main_cell->add(ref_translated); main_cell->add(ref_rotated); main_cell->add(ref_scaled); // Add the main cell to the library lib.add(main_cell); // Write the GDSII file lib.write_gds("transforms.gds"); return 0; } ``` -------------------------------- ### Build Python Wheel Package from Source Source: https://github.com/heitzmann/gdstk/blob/main/README.md Installs the build module and then compiles the GDSTK Python package wheel. Requires CMake and Ninja for faster compilation. The compiled package will be in the dist directory. ```sh pip install --user build python -m build -w ``` -------------------------------- ### Merge Libraries in C++ Source: https://github.com/heitzmann/gdstk/blob/main/docs/how-tos.rst Demonstrates merging two GDSII libraries into a single file using C++. This example includes a strategy for renaming cells to prevent name conflicts. ```c++ #include #include #include int main() { gdstk::Library lib1 = gdstk::read_rawcells("library1.gds"); gdstk::Library lib2 = gdstk::read_rawcells("library2.gds"); // Merge lib2 into lib1, renaming cells from lib2 to avoid collisions lib1.merge(lib2, "lib2_"); // Create a new library with the merged content gdstk::Library merged_lib("merged_library"); for (auto const& [name, cell] : lib1.cells) { merged_lib.add(cell); } merged_lib.write_gds("merged.gds"); return 0; } ``` -------------------------------- ### Render Text with Horizontal and Vertical Edges (C++) Source: https://github.com/heitzmann/gdstk/blob/main/docs/gettingstarted.rst This C++ snippet shows how to render text, similar to the Python example, ensuring compatibility with systems that require horizontal and vertical edges. ```c++ #include int main() { gdstk::Library lib; gdstk::Cell* cell = lib.new_cell("TEXT"); // Text uses only horizontal and vertical edges // This is important for some laser writing systems. gdstk::Text* text = new gdstk::Text("Hello GDSII!", 10, gdstk::Point(0, 0), 0, 0); cell->add(text); lib.write_gds("text.gds"); return 0; } ``` -------------------------------- ### Tapering width and offset changes along a path Source: https://context7.com/heitzmann/gdstk/llms.txt Demonstrates how to create a FlexPath with segments that linearly taper to new widths and offsets. Shows how to convert the path to polygons and inspect its spine and widths. ```python fp_taper = gdstk.FlexPath((0, 0), [0.3, 0.3], offset=0.5, layer=1) fp_taper.segment((5, 0)) fp_taper.segment((10, 0), width=0.8, offset=1.0) # linearly taper to new width/offset fp_taper.segment((15, 0)) # Convert to polygons and inspect spine polys = fp_taper.to_polygons() spine_pts = fp_taper.spine() # centerline points as ndarray widths = fp_taper.widths() # width at each spine point ``` -------------------------------- ### Mirror Polygon Across a Line Source: https://context7.com/heitzmann/gdstk/llms.txt Mirrors a polygon across a line defined by two points. The example mirrors across the y-axis. ```python mirrored = gdstk.rectangle((0, 0), (4, 2)) mirrored.mirror((0, 0), (0, 1)) ``` -------------------------------- ### Create a GDSII/OASIS Library Instance (Python) Source: https://github.com/heitzmann/gdstk/blob/main/docs/gettingstarted.rst This Python snippet shows how to create a `gdstk.Library` instance, which holds all geometric and hierarchical information for a GDSII/OASIS file, including name and units. ```python import gdstk # GDSII/OASIS Library lib = gdstk.Library('MyLibrary', unit=1e-6, precision=1e-9) ``` -------------------------------- ### Create an Arc Segment Source: https://context7.com/heitzmann/gdstk/llms.txt Generates a partial annular sector (arc). Specifies radii, start and end angles, and tolerance for approximation. ```python arc = gdstk.ellipse( (0, 0), radius=4, inner_radius=2, initial_angle=0, final_angle=numpy.pi, tolerance=0.01, layer=3 ) ``` -------------------------------- ### Create Circles in Python Source: https://github.com/heitzmann/gdstk/blob/main/docs/gettingstarted.rst Demonstrates how to create circles using the gdstk library in Python. Ensure the 'tutorial_images.py' script is available. ```python import gdstk lib = gdstk.Library() # cell, polygons cell = lib.new_cell('DEMO') # Circles poly1 = gdstk.ellipse(10, 5, 100, 0, 0) cell.add(poly1) poly2 = gdstk.ellipse(10, 5, 100, 0, 0, rotation=math.pi/4) cell.add(poly2) poly3 = gdstk.ellipse(10, 5, 100, 0, 0, rotation=math.pi/4, x_axis=100) cell.add(poly3) poly4 = gdstk.ellipse(10, 5, 100, 0, 0, rotation=math.pi/4, x_axis=100, y_axis=50) cell.add(poly4) poly5 = gdstk.ellipse(10, 5, 100, 0, 0, rotation=math.pi/4, x_axis=100, y_axis=50, x_radius=20) cell.add(poly5) poly6 = gdstk.ellipse(10, 5, 100, 0, 0, rotation=math.pi/4, x_axis=100, y_axis=50, x_radius=20, y_radius=10) cell.add(poly6) poly7 = gdstk.ellipse(10, 5, 100, 0, 0, rotation=math.pi/4, x_axis=100, y_axis=50, x_radius=20, y_radius=10, x_segments=10) cell.add(poly7) poly8 = gdstk.ellipse(10, 5, 100, 0, 0, rotation=math.pi/4, x_axis=100, y_axis=50, x_radius=20, y_radius=10, x_segments=10, y_segments=5) cell.add(poly8) lib.write_gds('tutorial_images.gds') ``` -------------------------------- ### Dilate or Erode Polygons (C++) Source: https://github.com/heitzmann/gdstk/blob/main/docs/gettingstarted.rst This C++ snippet shows how to dilate or erode polygons using the gdstk::offset function, similar to the Python example. ```c++ #include int main() { gdstk::Library lib; gdstk::Cell* cell = lib.new_cell("OFFSET"); // Create a polygon gdstk::Polygon* poly = new gdstk::Polygon(gdstk::rectangle(0, 0, 2, 2), 0, 0); // Dilate the polygon cell->add(gdstk::offset(poly, 0.5, 1, 0)); // Erode the polygon cell->add(gdstk::offset(poly, -0.5, 1, 1)); lib.write_gds("offset.gds"); return 0; } ``` -------------------------------- ### Create and write a Gdstk Library Source: https://context7.com/heitzmann/gdstk/llms.txt Initialize a Gdstk Library, add cells with geometry, and write the library to GDSII and OASIS files. Inspect layers and top-level cells, and rename or remove cells as needed. ```python import gdstk # Create a library with default unit=1e-6 m, precision=1e-9 m lib = gdstk.Library(name="MyDesign", unit=1e-6, precision=1e-9) # Add cells and write both GDSII and OASIS formats cell = lib.new_cell("TOP") cell.add(gdstk.rectangle((0, 0), (10, 5), layer=1)) lib.write_gds("output.gds", max_points=199) lib.write_oas("output.oas", compression_level=6, detect_rectangles=True) # Inspect layers used print(lib.layers_and_datatypes()) # {(1, 0)} print(lib.top_level()) # [] # Rename a cell lib.rename_cell("TOP", "CHIP") # Remove a cell lib.remove(lib.cells[0]) ``` -------------------------------- ### Perform Boolean Operations on Polygons (C++) Source: https://github.com/heitzmann/gdstk/blob/main/docs/gettingstarted.rst This C++ snippet illustrates performing boolean operations on polygons, mirroring the functionality shown in the Python example. ```c++ #include int main() { gdstk::Library lib; gdstk::Cell* cell = lib.new_cell("BOOLEAN"); // Create two polygons gdstk::Polygon* poly1 = new gdstk::Polygon(gdstk::rectangle(0, 0, 2, 2), 0, 0); gdstk::Polygon* poly2 = new gdstk::Polygon(gdstk::rectangle(1, 1, 3, 3), 0, 0); // Union cell->add(gdstk::boolean({poly1, poly2}, {}, gdstk::BooleanOpType::OR, 1, 0)); // Intersection cell->add(gdstk::boolean({poly1, poly2}, {}, gdstk::BooleanOpType::AND, 1, 1)); // Subtraction cell->add(gdstk::boolean({poly1, poly2}, {}, gdstk::BooleanOpType::NOT, 1, 2)); // Symmetric difference cell->add(gdstk::boolean({poly1, poly2}, {}, gdstk::BooleanOpType::XOR, 1, 3)); lib.write_gds("boolean.gds"); return 0; } ``` -------------------------------- ### Create a Parts Library in Python Source: https://github.com/heitzmann/gdstk/blob/main/docs/how-tos.rst Demonstrates creating a GDSII parts library with multiple components. This is useful for organizing reusable devices and integrating them into larger designs. ```python import gdstk # Alignment mark lib = gdstk.Library('photonics') cell_align = gdstk.Cell('ALIGNMENT_MARK') cell_align.add(gdstk.Rectangle([0, 0], [1, 1])) lib.add(cell_align) # Directional coupler cell_dc = gdstk.Cell('DIRECTIONAL_COUPLER') cell_dc.add(gdstk.Path(1, 0.5, [-1, 0], [-1, 1], [1, 1], [1, 0])) cell_dc.add(gdstk.Path(1, 0.5, [-1, -1], [-1, -2], [1, -2], [1, -1])) lib.add(cell_dc) # Mach-Zehnder interferometer cell_mzi = gdstk.Cell('MACH_ZEHNDER_INTERFEROMETER') coupler = lib.cells['DIRECTIONAL_COUPLER'] cell_mzi.add(gdstk.Reference(coupler, origin=[-2, 0], rotation=90)) cell_mzi.add(gdstk.Reference(coupler, origin=[2, 0], rotation=-90)) cell_mzi.add(gdstk.Path(1, 0.5, [-1, 0], [-2, 0])) cell_mzi.add(gdstk.Path(1, 0.5, [-1, -2], [-2, -2])) cell_mzi.add(gdstk.Path(1, 0.5, [1, 0], [2, 0])) cell_mzi.add(gdstk.Path(1, 0.5, [1, -2], [2, -2])) lib.add(cell_mzi) lib.write_gds('photonics.gds') ``` -------------------------------- ### Create a Flexible Path in Python Source: https://github.com/heitzmann/gdstk/blob/main/docs/gettingstarted.rst Demonstrates the creation of a flexible path with specified width, end caps, and joins. This is useful for designing paths with controlled geometry. ```python flex_path = gdstk.FlexPath(points=[(0, 0), (10, 0), (10, 10)], width=1, layer=1, datatype=1) flex_path.join_type = "round" flex_path.end_caps = "round" ``` -------------------------------- ### Round Polygon Corners (C++) Source: https://github.com/heitzmann/gdstk/blob/main/docs/gettingstarted.rst This C++ snippet shows how to round the corners of a polygon using the `gdstk::Polygon::fillet` method, mirroring the Python example. ```c++ #include int main() { gdstk::Library lib; gdstk::Cell* cell = lib.new_cell("FILLET"); // Create a polygon gdstk::Polygon* poly = new gdstk::Polygon(gdstk::rectangle(0, 0, 2, 2), 0, 0); // Round corners poly->fillet(0.5, 1, 0); cell->add(poly); lib.write_gds("fillet.gds"); return 0; } ``` -------------------------------- ### Define Polygons with Holes in Python Source: https://github.com/heitzmann/gdstk/blob/main/docs/gettingstarted.rst Define polygons with holes by connecting the hole boundary to the outer boundary of the polygon. This example shows a square with a triangular hole. ```python import gdstk # Holes polygon_with_hole = gdstk.polygon([(0, 0), (0, 3), (3, 3), (3, 0), (0, 0), (1, 1), (1, 2), (2, 2), (2, 1), (1, 1)]) cell.add(polygon_with_hole) ``` -------------------------------- ### Create a Flexible Path in C++ Source: https://github.com/heitzmann/gdstk/blob/main/docs/gettingstarted.rst This C++ snippet demonstrates the creation of a flexible path with basic properties like points, width, layer, and datatype. ```c++ std::vector> points1 = {{0, 0}, {10, 0}, {10, 10}}; std::vector> points2 = {{0, 0}, {10, 0}, {10, 10}}; std::vector> points3 = {{0, 0}, {10, 0}, {10, 10}}; gdstk::FlexPath fp1(points1, 1, 1, 1); fp1.join_type = gdstk::JoinType::ROUND; fp1.end_caps = gdstk::EndCaps::ROUND; gdstk::FlexPath fp2(points2, 1, 1, 1); fp2.join_type = gdstk::JoinType::ROUND; fp2.end_caps = gdstk::EndCaps::ROUND; fp2.bend_radius = 2; gdstk::FlexPath fp3(points3, {1, 2, 1}, 1, 1); fp3.join_type = gdstk::JoinType::ROUND; fp3.end_caps = gdstk::EndCaps::ROUND; ``` -------------------------------- ### Use a Library in Python Source: https://github.com/heitzmann/gdstk/blob/main/docs/how-tos.rst Demonstrates how to use a previously created GDSII library in a new layout. It utilizes `gdstk.read_rawcells` for efficient memory usage. ```python import gdstk lib = gdstk.read_rawcells('photonics.gds') layout = gdstk.Cell('LAYOUT') # Add components from the library coupler_ref = gdstk.Reference(lib.cells['DIRECTIONAL_COUPLER'], origin=[0, 0]) layout.add(coupler_ref) mzi_ref = gdstk::Reference(lib.cells['MACH_ZEHNDER_INTERFEROMETER'], origin=[5, 0]) layout.add(mzi_ref) # Create a new library and write the layout new_lib = gdstk.Library('layout_example') new_lib.add(layout) new_lib.write_gds('layout_example.gds') ``` -------------------------------- ### Set and Get Custom Polygon Properties Source: https://context7.com/heitzmann/gdstk/llms.txt Allows setting and retrieving custom string properties associated with a polygon object. Properties are returned as a list of lists. ```python poly.set_property("LAYER_NAME", "metal1") print(poly.get_property("LAYER_NAME")) ``` -------------------------------- ### Load GDSII/OASIS files with options Source: https://context7.com/heitzmann/gdstk/llms.txt Use `gdstk.read_gds` or `gdstk.read_oas` to load layout files. Options include unit conversion, layer filtering, and accessing file metadata without loading all geometry. ```python import gdstk # Load with original units preserved lib = gdstk.read_gds("chip.gds") print(f"unit={lib.unit}, precision={lib.precision}") print([c.name for c in lib.cells]) # Convert all coordinates to nanometres lib_nm = gdstk.read_gds("chip.gds", unit=1e-9) # Load only specific layer/datatype combinations (faster for large files) lib_filtered = gdstk.read_gds( "chip.gds", filter=[(1, 0), (2, 0), (10, 3)] # only load these (layer, datatype) pairs ) # Load OASIS file (unit is always auto-detected as 1e-6 unless overridden) lib_oas = gdstk.read_oas("chip.oas") # Validate OASIS checksum and get precision valid, checksum = gdstk.oas_validate("chip.oas") precision = gdstk.oas_precision("chip.oas") # Inspect file metadata without loading all geometry info = gdstk.gds_info("chip.gds") unit, precision = gdstk.gds_units("chip.gds") # Access a specific cell by name top = lib.top_level() # cells not referenced by any other cell mzi = lib["MZI"] # shorthand dict-like access deps = mzi.dependencies(recursive=True) # all cells MZI depends on ``` -------------------------------- ### Get and Materialize Repetition Offsets with gdstk Source: https://context7.com/heitzmann/gdstk/llms.txt Demonstrates how to retrieve all calculated copy positions from a Repetition object and how to materialize these copies as new geometric objects within a cell. ```python import gdstk # Get all actual copy positions square = gdstk.regular_polygon((0, 0), side_length=1, sides=4, layer=1) square.repetition = gdstk.Repetition(columns=5, rows=3, spacing=(10, 8)) all_offsets = square.repetition.get_offsets() # numpy ndarray of shape (N, 2) print(all_offsets.shape) # (15, 2) # Materialize copies as new objects (for subsequent boolean operations, etc.) cell = gdstk.Cell("GRID") cell.add(square) all_copies = cell.get_polygons(apply_repetitions=True) # flattened list ``` -------------------------------- ### Find Python Components with CMake Source: https://github.com/heitzmann/gdstk/blob/main/python/CMakeLists.txt Locates the Python interpreter, development headers, and NumPy library required for building Python extensions. Ensure Python is installed and discoverable by CMake. ```cmake find_package(Python COMPONENTS Interpreter Development.Module NumPy REQUIRED) ``` -------------------------------- ### Create First Layout in Python Source: https://github.com/heitzmann/gdstk/blob/main/docs/gettingstarted.rst Create a GDSII library, add a cell with a rectangle, and save the library to GDSII and OASIS files. Optionally save an SVG image of the cell. ```python import gdstk # The GDSII file is called a library, which contains multiple cells. lib = gdstk.Library() # Geometry must be placed in cells. cell = lib.new_cell("FIRST") # Create the geometry (a single rectangle) and add it to the cell. rect = gdstk.rectangle((0, 0), (2, 1)) cell.add(rect) # Save the library in a GDSII or OASIS file. lib.write_gds("first.gds") lib.write_oas("first.oas") # Optionally, save an image of the cell as SVG. cell.write_svg("first.svg") ``` -------------------------------- ### Create Bézier Curves in Python Source: https://github.com/heitzmann/gdstk/blob/main/docs/gettingstarted.rst Demonstrates the creation of Bézier curves (cubic, quadratic, and general-degree) using gdstk.Curve in Python. Requires 'tutorial_images.py'. ```python import gdstk import math lib = gdstk.Library() # cell, polygons cell = lib.new_cell('DEMO') # Curves 2 curve1 = gdstk.Curve().move((0,0)).bezier([(10,10), (20, -10), (30,0)]) cell.add(curve1) curve2 = gdstk.Curve().move((0,0)).quadratic([(10,10), (20,0)]) cell.add(curve2) curve3 = gdstk.Curve().move((0,0)).quadratic([(10,10), (20,0), (30,10)]) cell.add(curve3) curve4 = gdstk.Curve().move((0,0)).quadratic([(10,10), (20,0), (30,10), (40,0)]) cell.add(curve4) curve5 = gdstk.Curve().move((0,0)).quadratic([(10,10), (20,0), (30,10), (40,0), (50,10)]) cell.add(curve5) curve6 = gdstk.Curve().move((0,0)).quadratic([(10,10), (20,0), (30,10), (40,0), (50,10), (60,0)]) cell.add(curve6) curve7 = gdstk.Curve().move((0,0)).quadratic([(10,10), (20,0), (30,10), (40,0), (50,10), (60,0), (70,10)]) cell.add(curve7) curve8 = gdstk.Curve().move((0,0)).quadratic([(10,10), (20,0), (30,10), (40,0), (50,10), (60,0), (70,10), (80,0)]) cell.add(curve8) lib.write_gds('tutorial_images.gds') ``` -------------------------------- ### Slice Polygons along Cut Lines (C++) Source: https://github.com/heitzmann/gdstk/blob/main/docs/gettingstarted.rst This C++ snippet shows how to perform a slice operation on polygons using specified cut lines, similar to the Python example. ```c++ #include int main() { gdstk::Library lib; gdstk::Cell* cell = lib.new_cell("SLICE"); // Create a polygon gdstk::Polygon* poly = new gdstk::Polygon(gdstk::rectangle(0, 0, 4, 4), 0, 0); // Slice along horizontal and vertical lines gdstk::Path* path1 = new gdstk::Path(1, gdstk::Point(0, 2), 0); path1->horizontal(2); gdstk::Path* path2 = new gdstk::Path(1, gdstk::Point(2, 0), 0); path2->vertical(2); cell->add(gdstk::slice(poly, {path1, path2}, 1, 0)); lib.write_gds("slice.gds"); return 0; } ``` -------------------------------- ### Apply Transformations to Polygons in Python Source: https://github.com/heitzmann/gdstk/blob/main/docs/gettingstarted.rst Shows how to apply in-place transformations (translate, rotate, scale, mirror) to gdstk.Polygon objects in Python. Requires 'tutorial_images.py'. ```python import gdstk import math lib = gdstk.Library() # cell, polygons cell = lib.new_cell('DEMO') # Transformations poly1 = gdstk.rectangle(0, 1, 0, 1) cell.add(poly1) poly2 = gdstk.rectangle(0, 1, 0, 1) poly2.translate(10, 0) cell.add(poly2) poly3 = gdstk.rectangle(0, 1, 0, 1) poly3.rotate(math.pi/4) cell.add(poly3) poly4 = gdstk.rectangle(0, 1, 0, 1) poly4.scale(2, 0.5) cell.add(poly4) poly5 = gdstk.rectangle(0, 1, 0, 1) poly5.mirror((0,0), (1,1)) cell.add(poly5) poly6 = gdstk.rectangle(0, 1, 0, 1) poly6.translate(10, 0).rotate(math.pi/4).scale(2, 0.5).mirror((0,0), (1,1)) cell.add(poly6) lib.write_gds('tutorial_images.gds') ``` -------------------------------- ### Layer and Datatype Assignment in Python Source: https://github.com/heitzmann/gdstk/blob/main/docs/gettingstarted.rst Demonstrates assigning layer and datatype properties to shapes using Python dictionaries. Requires 'tutorial_images.py'. ```python import gdstk import math lib = gdstk.Library() # cell, polygons cell = lib.new_cell('DEMO') # Layer and Datatype polygons = { (1, 0): gdstk.rectangle(0, 1, 0, 1), (1, 1): gdstk.rectangle(1, 2, 0, 1), (2, 0): gdstk.rectangle(0, 1, 1, 2), (2, 1): gdstk.rectangle(1, 2, 1, 2) } for layer, datatype in polygons: polygons[(layer, datatype)].layer = layer polygons[(layer, datatype)].datatype = datatype cell.add(polygons[(layer, datatype)]) lib.write_gds('tutorial_images.gds') ``` -------------------------------- ### Filter Geometry within a Region Source: https://github.com/heitzmann/gdstk/blob/main/docs/how-tos.rst Shows how to remove geometry that overlaps a particular shape using gdstk.inside. This example creates a periodic background and then filters elements within a specified region. ```python from tutorial_images import draw import gdstk main = gdstk.Cell("MAIN") # Create a periodic background rect = gdstk.Rectangle(0, 0, 1, 1) array = gdstk.Reference(rect, vlen=[10, 10], spacing=[2, 2]) main.add(array) # Define a region to filter by region = gdstk.Rectangle(3, 3, 6, 6) # Filter elements inside the region filtered_elements = [e for e in main.get_elements() if gdstk.inside(e, region)] # Create a new cell with only the filtered elements filtered_cell = gdstk.Cell("FILTERED") filtered_cell.add(filtered_elements) # Create a library and add the cell lib = gdstk.Library("lib") lib.add(filtered_cell) # Write the GDSII file lib.write_gds("pos_filtering.gds") draw(lib, "pos_filtering.svg") ``` -------------------------------- ### Create a Robust Path in Python Source: https://github.com/heitzmann/gdstk/blob/main/docs/gettingstarted.rst Demonstrates the creation of a robust path, which is suitable for scenarios where FlexPath might struggle with complex joins. This offers more robustness at the cost of computational resources. ```python robust_path = gdstk.RobustPath(points=[(0, 0), (10, 0), (10, 10)], width=1, layer=1, datatype=1) robust_path.join_type = "miter" robust_path.end_caps = "extended" ``` -------------------------------- ### Create a Flexible Path with Circular Bends in Python Source: https://github.com/heitzmann/gdstk/blob/main/docs/gettingstarted.rst Illustrates how to create a flexible path with automatic circular bends for curved sections. This is useful when smooth transitions are required. ```python flex_path = gdstk.FlexPath(points=[(0, 0), (10, 0), (10, 10)], width=1, layer=1, datatype=1) flex_path.join_type = "round" flex_path.end_caps = "round" flex_path.bend_radius = 2 ``` -------------------------------- ### Create Curves in Python Source: https://github.com/heitzmann/gdstk/blob/main/docs/gettingstarted.rst Illustrates the creation of polygons using the gdstk.Curve class in Python, mimicking SVG path syntax. Requires 'tutorial_images.py'. ```python import gdstk import math lib = gdstk.Library() # cell, polygons cell = lib.new_cell('DEMO') # Curves curve1 = gdstk.Curve().segment([(0,0), (10,5), (15,15)]).arc(10, 5, 100, 0, 0).segment([(20,10), (25,0)]).close() cell.add(curve1) curve2 = gdstk.Curve().move((0,0)).arc(10, 5, 100, 0, 0, rotation=math.pi/4).line((10,10)).arc(5, 5, 100, 0, 0, rotation=math.pi/4, start_angle=math.pi/2, end_angle=0).line((0,0)).close() cell.add(curve2) curve3 = gdstk.Curve().move((0,0)).arc(10, 5, 100, 0, 0, rotation=math.pi/4, x_axis=100).line((10,10)).arc(5, 5, 100, 0, 0, rotation=math.pi/4, x_axis=100, start_angle=math.pi/2, end_angle=0).line((0,0)).close() cell.add(curve3) curve4 = gdstk.Curve().move((0,0)).arc(10, 5, 100, 0, 0, rotation=math.pi/4, x_axis=100, y_axis=50).line((10,10)).arc(5, 5, 100, 0, 0, rotation=math.pi/4, x_axis=100, y_axis=50, start_angle=math.pi/2, end_angle=0).line((0,0)).close() cell.add(curve4) curve5 = gdstk.Curve().move((0,0)).arc(10, 5, 100, 0, 0, rotation=math.pi/4, x_axis=100, y_axis=50, x_radius=20).line((10,10)).arc(5, 5, 100, 0, 0, rotation=math.pi/4, x_axis=100, y_axis=50, x_radius=20, start_angle=math.pi/2, end_angle=0).line((0,0)).close() cell.add(curve5) curve6 = gdstk.Curve().move((0,0)).arc(10, 5, 100, 0, 0, rotation=math.pi/4, x_axis=100, y_axis=50, x_radius=20, y_radius=10).line((10,10)).arc(5, 5, 100, 0, 0, rotation=math.pi/4, x_axis=100, y_axis=50, x_radius=20, y_radius=10, start_angle=math.pi/2, end_angle=0).line((0,0)).close() cell.add(curve6) curve7 = gdstk.Curve().move((0,0)).arc(10, 5, 100, 0, 0, rotation=math.pi/4, x_axis=100, y_axis=50, x_radius=20, y_radius=10, x_segments=10).line((10,10)).arc(5, 5, 100, 0, 0, rotation=math.pi/4, x_axis=100, y_axis=50, x_radius=20, y_radius=10, x_segments=10, start_angle=math.pi/2, end_angle=0).line((0,0)).close() cell.add(curve7) curve8 = gdstk.Curve().move((0,0)).arc(10, 5, 100, 0, 0, rotation=math.pi/4, x_axis=100, y_axis=50, x_radius=20, y_radius=10, x_segments=10, y_segments=5).line((10,10)).arc(5, 5, 100, 0, 0, rotation=math.pi/4, x_axis=100, y_axis=50, x_radius=20, y_radius=10, x_segments=10, y_segments=5, start_angle=math.pi/2, end_angle=0).line((0,0)).close() cell.add(curve8) lib.write_gds('tutorial_images.gds') ``` -------------------------------- ### Filter Geometry by Layer and Type Source: https://github.com/heitzmann/gdstk/blob/main/docs/how-tos.rst Demonstrates filtering geometry by iterating over cells and objects, testing, and removing unwanted elements. This example removes polygons in layer 2 and paths in layer 10. ```python from tutorial_images import draw import gdstk # Load the layout created in a previous example lib = gdstk.read_gds("library.gds") # Iterate over cells and remove polygons in layer 2 and paths in layer 10 for cell in lib.cells(): cell.polygons = [p for p in cell.polygons if p.layer != 2] cell.paths = [p for p in cell.paths if p.layer != 10] # Write the filtered GDSII file lib.write_gds("filtering.gds") draw(lib, "filtering.svg") ``` -------------------------------- ### Merge Libraries in Python Source: https://github.com/heitzmann/gdstk/blob/main/docs/how-tos.rst Shows how to merge multiple GDSII files into a single new GDSII file. This example handles potential cell name collisions by renaming cells during the merge process. ```python import gdstk import pathlib path = pathlib.Path('.') lib1 = gdstk.read_rawcells(path / 'library1.gds') lib2 = gdstk.read_rawcells(path / 'library2.gds') # Merge lib2 into lib1, renaming cells from lib2 to avoid collisions lib1.merge(lib2, prefix='lib2_') # Create a new library with the merged content merged_lib = gdstk.Library('merged_library') merged_lib.add(lib1.cells.values()) merged_lib.write_gds('merged.gds') ``` -------------------------------- ### Create a Flexible Path with Width Variations in Python Source: https://github.com/heitzmann/gdstk/blob/main/docs/gettingstarted.rst Shows how to define a flexible path with varying width along its length. Note that width variations will cause the path to be stored as polygons in GDSII/OASIS files. ```python flex_path = gdstk.FlexPath(points=[(0, 0), (10, 0), (10, 10)], width=[1, 2, 1], layer=1, datatype=1) flex_path.join_type = "round" flex_path.end_caps = "round" ``` -------------------------------- ### Create Multi-Width FlexPath with Custom Joins and Ends Source: https://context7.com/heitzmann/gdstk/llms.txt Constructs a FlexPath with multiple parallel sub-paths, each having potentially different widths, offsets, join styles, and end cap styles. ```python fp_multi = gdstk.FlexPath( (0, 0), width=[0.4, 0.2, 0.4], offset=[-0.6, 0, 0.6], joins=["bevel", "miter", "round"], ends=["extended", "flush", "round"], layer=[1, 1, 1], datatype=[0, 1, 0], ) fp_multi.segment((10, 0)) fp_multi.turn(radius=2, angle=numpy.pi / 2) fp_multi.segment((0, 5), relative=True) fp_multi.arc(radius=1, initial_angle=0, final_angle=numpy.pi) ``` -------------------------------- ### Text annotation using Label Source: https://context7.com/heitzmann/gdstk/llms.txt Places text annotations on a specified layer and texttype using gdstk.Label. These are metadata for EDA tools, not rendered geometry. Includes example of adding to a cell and retrieving labels. ```python import gdstk # Basic label at origin lbl = gdstk.Label( text="VDD", origin=(5.0, 10.0), anchor="sw", # anchor: n/s/e/w/ne/nw/se/sw/o (o = center) rotation=0.0, magnification=1.0, x_reflection=False, layer=5, texttype=2, ) # Add to a cell cell = gdstk.Cell("LABELS") cell.add(lbl) # Use gdstk.text() for polygonal (rendered) text instead of annotation labels rendered = gdstk.text("OUTPUT", size=3.0, position=(0, 0), layer=1) cell.add(*rendered) # Retrieve labels filtered by layer labels = cell.get_labels(layer=5, texttype=2) print(labels[0].text) # 'VDD' print(labels[0].origin) # (5.0, 10.0) ``` -------------------------------- ### Loading Layout Files Source: https://github.com/heitzmann/gdstk/blob/main/docs/gettingstarted.rst Functions for loading GDSII and OASIS files into a gdstk.Library instance, with support for unit conversion. ```APIDOC ## Loading a Layout File The functions :func:`gdstk.read_gds` and :func:`gdstk.read_oas` load an existing GDSII or OASIS file into a new instance of :class:`gdstk.Library`. ### Python Example ```python # Load a GDSII file into a new library. lib1 = gdstk.read_gds("filename.gds") # Verify the unit used in the library. print(lib1.unit) # Load the same file, but convert all units to nm. lib2 = gdstk.read_gds("filename.gds", 1e-9) # Load an OASIS file into a third library. # The library will use unit=1e-6, the default for OASIS. lib3 = gdstk.read_oas("filename.oas") ``` ### C++ Example ```cpp // Use units from infile Library lib1 = read_gds("filename.gds", 0); // Convert to new unit Library lib2 = read_gds("filename.gds", 1e-9); // Use default OASIS unit (1e-6) Library lib3 = read_oas("filename.oas"); ``` Access to the cells in the loaded library is primarily provided through the list :attr:`gdstk.Library.cells`. As a shorthand, if the desired cell name is know, the idiom ``lib1["CELL_NAME"]`` can be used. Additionally, the method :meth:`gdstk.Library.top_level` can be used to find the top-level cells in the library. ```