Regions

For original class documentation see Region class reference.

Regions are basically collections of polygons. A simple application is to create a region object and insert polygons. Region objects support many geometrical operations such as sizing (enlargement, biasing), boolean operations (AND, NOT, XOR), merging (removing overlaps).

However, Region objects are much more powerful. They can be fed from a hierarchical layer. This enables operations on layouts. Regions support a hierarchical mode (“deep mode”) that allows preserving the hierarchy of the original layout as far as possible.

With this ability, Region objects are also the basis of KLayout’s DRC (design rule check) feature. All features available in DRC decks are mapped to Region methods.

I will discuss only the basic features here. The original documentation is the entry point for further explanations.

Region Creation

Region objects can be filled with integer-unit polygons. When inserting other graphic objects they are converted to polygons (note that we are using the default database unit of 1 nm here):

import klayout.db as db

r = db.Region()

r.insert(db.Box(0, 3000, 1000, 4000))

points = [
  db.Point(0, 1000), db.Point(3000, 1000), db.Point(3000, 4000)
]
r.insert(db.Path(points, 2000))

Gives:

Result

Note that there are not micrometer-unit regions currently. A trick to convert micrometer-units into integer-unit objects is a apply a complex transformation:

import klayout.db as db

dbu = 0.001

t = db.CplxTrans(dbu).inverted()

r = db.Region()

r.insert(t * db.DBox(0.0, 3.0, 1.0, 4.0))

points = [
  db.DPoint(0.0, 1.0), db.DPoint(3.0, 1.0), db.DPoint(3.0, 4.0)
]
r.insert(t * db.DPath(points, 2.0))

Gives:

Result

Region Operations

“Sizing” (also called “biasing”) is an operation that shifts the polygon edges by a certain distance. Positive values will shift outside, negative values inside. Before the edges are shifted, the polygons are merged:

import klayout.db as db

region = db.Region()

region.insert(db.Box(0, 0, 3000, 4000))
region.insert(db.Box(2000, 0, 6000, 2000))

sized_region = region.sized(1000)


Gives (the original polygons are white):

Result

Sizing can be anisotropic - in this case, the horizontal shift can be different from the vertical shift:

import klayout.db as db

region = db.Region()

region.insert(db.Box(0, 0, 3000, 4000))
region.insert(db.Box(2000, 0, 6000, 2000))

# "2" is the default cutoff mode. It is mandatory for
# anisotropic sizing.
sized_region = region.sized(0, 2000, 2)


Gives (the original polygons are white):

Result

The boolean “NOT” operation subtracts the second region from the first. This operation is implemented by the - operator:

import klayout.db as db

r1 = db.Region()
r1.insert(db.Box(0, 0, 3000, 4000))

r2 = db.Region()
r2.insert(db.Box(1000, 1000, 6000, 2000))

result = r1 - r2

Gives (the result is white):

Result

The boolean “AND” computes the intersection of two regions. This operation is implemented by the & operator:

import klayout.db as db

r1 = db.Region()
r1.insert(db.Box(0, 0, 3000, 4000))

r2 = db.Region()
r2.insert(db.Box(1000, 1000, 6000, 2000))

result = r1 & r2

Gives (the result is white):

Result

The boolean “XOR” computes the intersection of two regions. This operation is implemented by the ^ operator:

import klayout.db as db

r1 = db.Region()
r1.insert(db.Box(0, 0, 3000, 4000))

r2 = db.Region()
r2.insert(db.Box(1000, 1000, 6000, 2000))

result = r1 ^ r2

Gives (the result is white):

Result

The + operator joins two collections. merge (in place) or merged merges the polygons of a region, i.e. it computes the envelopes or boolean “OR” of the polygons:

import klayout.db as db

r1 = db.Region()
r1.insert(db.Box(0, 0, 3000, 4000))

r2 = db.Region()
r2.insert(db.Box(1000, 1000, 6000, 2000))

result = (r1 + r2).merged()

Gives (the result is white):

Result

Regions from Layout Layers

You can pull polygons from a layout layer hierarchically and perform operations on it (Download my_layout.gds):

import klayout.db as db

ly_file = db.Layout()
ly_file.read("my_layout.gds")

l1 = ly_file.layer(1, 0)
r1 = db.Region(ly_file.top_cell().begin_shapes_rec(l1))

l2 = ly_file.layer(2, 0)
r2 = db.Region(ly_file.top_cell().begin_shapes_rec(l2))

# Note: the database unit is 1 nm, so 300 corresponds to 0.3 µm
result = r1.sized(300) + r2.sized(-300)


Gives (the result are the white features):

Result

Download the GDS file