Source code for gdsfactory.geometry.union

from __future__ import annotations

import gdstk

import gdsfactory as gf
from gdsfactory.component import Component
from gdsfactory.typings import Layer


def _union_polygons(polygons, precision: float = 1e-4) -> gdstk.Polygon:
    """Performs union of polygons within PolygonSet or list of polygons.

    Args:
        polygons: PolygonSet or list of polygons. A set containing the input polygons.
        precision: Desired precision for rounding vertex coordinates.
        max_points: maximum number of vertices within the resulting polygon.

    Returns:
        unioned: polygon result of the union of all polygons within the input PolygonSet.
    """
    return gdstk.boolean(
        polygons,
        [],
        operation="or",
        precision=precision,
    )


[docs] @gf.cell def union( component: Component, by_layer: bool = False, precision: float = 1e-4, join_first: bool = True, layer: Layer = (1, 0), keep_ports: bool = False, ) -> Component: """Returns new Component with inverted union of Component polygons. based on phidl.geometry.union Args: component: Component(/Reference), list of Component(/Reference), or Polygon \ A containing the polygons to perform union and inversion on. by_layer: performs the union operation layer-wise so each layer can be \ individually combined. precision: Desired precision for rounding vertex coordinates. join_first: before offsetting to avoid unnecessary joins in adjacent polygons. layer: Specific layer to put polygon geometry on. keep_ports: keep ports from component. .. plot:: :include-source: import gdsfactory as gf c = gf.Component() c << gf.components.ellipse(radii=(6, 6)) c << gf.components.ellipse(radii=(10, 4)) c2 = gf.geometry.union(c, join_first=False) c2.plot() """ U = Component() if by_layer: all_polygons = component.get_polygons(by_spec=True) for layer, polygons in all_polygons.items(): unioned_polygons = _union_polygons( polygons, precision=precision, ) U.add_polygon(unioned_polygons, layer=layer) else: all_polygons = component.get_polygons(by_spec=False) unioned_polygons = ( _union_polygons( all_polygons, precision=precision, ) if join_first else all_polygons ) U.add_polygon(unioned_polygons, layer=layer) if keep_ports: U.add_ports(component.ports) return U
def test_union() -> None: c = Component() _ = c << gf.components.ellipse(radii=(6, 6)) _ = c << gf.components.ellipse(radii=(10, 4)) c2 = union(c) assert int(c2.area()) == 153, c2.area() if __name__ == "__main__": test_union() c = Component() _ = c << gf.components.ellipse(radii=(6, 6)) _ = c << gf.components.ellipse(radii=(10, 4)) c2 = union(c, join_first=False, keep_ports=True) c2.show()