Skip to content

Shapes

shapes

VShapes

Emulate [klayout.db.Shapes][klayout.db.Shapes].

Source code in kfactory/shapes.py
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
class VShapes:
    """Emulate `[klayout.db.Shapes][klayout.db.Shapes]`."""

    cell: VKCell
    _shapes: list[ShapeLike]
    _bbox: kdb.DBox

    def __init__(
        self, cell: VKCell, _shapes: Sequence[ShapeLike] | None = None
    ) -> None:
        """Initialize the shapes."""
        self.cell = cell
        self._shapes = list(_shapes) if _shapes is not None else []
        self._bbox = kdb.DBox()

    def insert(self, shape: ShapeLike) -> None:
        """Emulate `[klayout.db.Shapes][klayout.db.Shapes]'s insert'`."""
        if (
            isinstance(shape, kdb.Shape)
            and shape.cell.layout().dbu != self.cell.kcl.dbu
        ):
            raise ValueError
        if isinstance(shape, kdb.Box):
            shape = self.cell.kcl.to_um(shape)
        if isinstance(shape, kdb.DBox):
            shape = kdb.DPolygon(shape)
        self._shapes.append(shape)
        b = shape.bbox()
        if isinstance(b, kdb.Box):
            self._bbox += self.cell.kcl.to_um(b)
        else:
            self._bbox += b

    def bbox(self) -> kdb.DBox:
        """Emulate `[klayout.db.Shapes][klayout.db.Shapes]'s bbox'`."""
        return self._bbox.dup()

    def __iter__(self) -> Iterator[ShapeLike]:
        """Emulate `[klayout.db.Shapes][klayout.db.Shapes]'s __iter__'`."""
        yield from self._shapes

    def each(self) -> Iterator[ShapeLike]:
        """Emulate `[klayout.db.Shapes][klayout.db.Shapes]'s each'`."""
        yield from self._shapes

    def transform(
        self,
        trans: kdb.Trans | kdb.DTrans | kdb.ICplxTrans | kdb.DCplxTrans,
        /,
    ) -> VShapes:
        """Emulate `[klayout.db.Shapes][klayout.db.Shapes]'s transform'`."""
        new_shapes: list[DShapeLike] = []
        if isinstance(trans, kdb.Trans):
            trans = trans.to_dtype(self.cell.kcl.dbu)
        elif isinstance(trans, kdb.ICplxTrans):
            trans = trans.to_itrans(self.cell.kcl.dbu)

        for shape in self._shapes:
            if dshape_guard(shape):
                new_shapes.append(shape.transformed(trans))
            elif ishape_guard(shape):
                if isinstance(shape, kdb.Region):
                    new_shapes.extend(
                        poly.to_dtype(self.cell.kcl.dbu).transformed(trans)
                        for poly in shape.each()
                    )
                else:
                    new_shapes.append(
                        shape.to_dtype(self.cell.kcl.dbu).transformed(trans)
                    )
            else:
                new_shapes.append(cast("kdb.Shape", shape).dpolygon.transform(trans))

        return VShapes(cell=self.cell, _shapes=new_shapes)

    def size(self) -> int:
        """Emulate `[klayout.db.Shapes][klayout.db.Shapes]'s size'`."""
        return len(self._shapes)

__init__

__init__(
    cell: VKCell, _shapes: Sequence[ShapeLike] | None = None
) -> None

Initialize the shapes.

Source code in kfactory/shapes.py
25
26
27
28
29
30
31
def __init__(
    self, cell: VKCell, _shapes: Sequence[ShapeLike] | None = None
) -> None:
    """Initialize the shapes."""
    self.cell = cell
    self._shapes = list(_shapes) if _shapes is not None else []
    self._bbox = kdb.DBox()

__iter__

__iter__() -> Iterator[ShapeLike]

Emulate [klayout.db.Shapes][klayout.db.Shapes]'s __iter__'.

Source code in kfactory/shapes.py
55
56
57
def __iter__(self) -> Iterator[ShapeLike]:
    """Emulate `[klayout.db.Shapes][klayout.db.Shapes]'s __iter__'`."""
    yield from self._shapes

bbox

bbox() -> kdb.DBox

Emulate [klayout.db.Shapes][klayout.db.Shapes]'s bbox'.

Source code in kfactory/shapes.py
51
52
53
def bbox(self) -> kdb.DBox:
    """Emulate `[klayout.db.Shapes][klayout.db.Shapes]'s bbox'`."""
    return self._bbox.dup()

each

each() -> Iterator[ShapeLike]

Emulate [klayout.db.Shapes][klayout.db.Shapes]'s each'.

Source code in kfactory/shapes.py
59
60
61
def each(self) -> Iterator[ShapeLike]:
    """Emulate `[klayout.db.Shapes][klayout.db.Shapes]'s each'`."""
    yield from self._shapes

insert

insert(shape: ShapeLike) -> None

Emulate [klayout.db.Shapes][klayout.db.Shapes]'s insert'.

Source code in kfactory/shapes.py
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
def insert(self, shape: ShapeLike) -> None:
    """Emulate `[klayout.db.Shapes][klayout.db.Shapes]'s insert'`."""
    if (
        isinstance(shape, kdb.Shape)
        and shape.cell.layout().dbu != self.cell.kcl.dbu
    ):
        raise ValueError
    if isinstance(shape, kdb.Box):
        shape = self.cell.kcl.to_um(shape)
    if isinstance(shape, kdb.DBox):
        shape = kdb.DPolygon(shape)
    self._shapes.append(shape)
    b = shape.bbox()
    if isinstance(b, kdb.Box):
        self._bbox += self.cell.kcl.to_um(b)
    else:
        self._bbox += b

size

size() -> int

Emulate [klayout.db.Shapes][klayout.db.Shapes]'s size'.

Source code in kfactory/shapes.py
93
94
95
def size(self) -> int:
    """Emulate `[klayout.db.Shapes][klayout.db.Shapes]'s size'`."""
    return len(self._shapes)

transform

transform(
    trans: Trans | DTrans | ICplxTrans | DCplxTrans,
) -> VShapes

Emulate [klayout.db.Shapes][klayout.db.Shapes]'s transform'.

Source code in kfactory/shapes.py
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
def transform(
    self,
    trans: kdb.Trans | kdb.DTrans | kdb.ICplxTrans | kdb.DCplxTrans,
    /,
) -> VShapes:
    """Emulate `[klayout.db.Shapes][klayout.db.Shapes]'s transform'`."""
    new_shapes: list[DShapeLike] = []
    if isinstance(trans, kdb.Trans):
        trans = trans.to_dtype(self.cell.kcl.dbu)
    elif isinstance(trans, kdb.ICplxTrans):
        trans = trans.to_itrans(self.cell.kcl.dbu)

    for shape in self._shapes:
        if dshape_guard(shape):
            new_shapes.append(shape.transformed(trans))
        elif ishape_guard(shape):
            if isinstance(shape, kdb.Region):
                new_shapes.extend(
                    poly.to_dtype(self.cell.kcl.dbu).transformed(trans)
                    for poly in shape.each()
                )
            else:
                new_shapes.append(
                    shape.to_dtype(self.cell.kcl.dbu).transformed(trans)
                )
        else:
            new_shapes.append(cast("kdb.Shape", shape).dpolygon.transform(trans))

    return VShapes(cell=self.cell, _shapes=new_shapes)