Example #1
0
    def resize(self, dx, dbu):
        """ Resizes the polygon by a positive or negative quantity dx.
        Args:
            dbu: typically 0.001
        """

        dpoly = pya.DPolygon(self)
        dpoly.size(dx, 5)
        dpoly = pya.EdgeProcessor().simple_merge_p2p([dpoly.to_itype(dbu)], False, False, 1)
        dpoly = dpoly[0].to_dtype(dbu)  # pya.DPolygon

        def norm(p):
            return sqrt(p.x**2 + p.y**2)

        # Filter edges if they are too small
        points = list(dpoly.each_point_hull())
        new_points = list([points[0]])
        for i in range(0, len(points)):
            delta = points[i] - new_points[-1]
            if norm(delta) > min(10 * dbu, abs(dx)):
                new_points.append(points[i])

        sdpoly = DSimplePolygon(new_points)  # convert to SimplePolygon
        self.assign(sdpoly)
        return self
Example #2
0
 def produce_impl(self):
     dbu = self.layout.dbu
     # resolve path
     info = pya.QFileInfo(self.path)
     if info.isRelative():
         view = pya.Application.instance().main_window().current_view()
         designfile = view.active_cellview().filename()
         if designfile == "":
             self.error = "Error: In order to use relative file path, design must be saved first"
             return
         designdir = pya.QFileInfo(designfile).dir()
         path = designdir.absoluteFilePath(self.path)
     else:
         path = self.path
     # open image
     image = pya.QImage(path)
     if image.isNull():
         self.error = "Error opening image"
         return
     image = image.convertToFormat(pya.QImage.Format_Grayscale8)
     width = image.width()
     height = image.height()
     tilesx = math.ceil(width / self.t)
     tilesy = math.ceil(height / self.t)
     for tiley in range(tilesy):
         for tilex in range(tilesx):
             tile = image.copy(tilex * self.t, tiley * self.t, self.t,
                               self.t)
             polygons = []
             # generate pixels
             rangex = rangey = self.t
             if self.t * (tilex + 1) > width:
                 rangex = width % self.t
             if self.t * (tiley + 1) > height:
                 rangey = height % self.t
             for y in range(rangey):
                 for x in range(rangex):
                     color = pya.QColor(tile.pixel(x, y))
                     color = (color.red + color.green + color.blue) / 3
                     if (color > self.th
                             and not self.inv) or (color <= self.th
                                                   and self.inv):
                         x1 = (tilex * self.t + x) * self.px / dbu
                         y1 = -(tiley * self.t + y) * self.px / dbu
                         x2 = (tilex * self.t + x + 1) * self.px / dbu
                         y2 = -(tiley * self.t + y + 1) * self.px / dbu
                         polygons.append(
                             pya.Polygon(
                                 pya.Box(
                                     pya.Point.from_dpoint(
                                         pya.DPoint(x1, y1)),
                                     pya.Point.from_dpoint(
                                         pya.DPoint(x2, y2)))))
             # merge
             processor = pya.EdgeProcessor()
             merged = processor.simple_merge_p2p(polygons, False, False)
             for polygon in merged:
                 self.cell.shapes(self.l_layer).insert(polygon)
     self.error = None
 def extend_photo_overetching(self):
     tmp_reg = Region()
     ep = pya.EdgeProcessor()
     for poly in self.region_ph.each():
         tmp_reg.insert(
             ep.simple_merge_p2p([
                 poly.sized(FABRICATION.OVERETCHING,
                            FABRICATION.OVERETCHING, 2)
             ], False, False, 1))
     self.region_ph = tmp_reg
Example #4
0
def extended_region(reg, extension=0):
    """
    extends region in outer direction by `extension` value.
    extension is orthogonal to region`s polygons edges.
    Parameters
    ----------
    reg : Region
        pya.Region instance
    extension : float
        extension in nm
    Returns
    -------
    Region
        extended version of region
    """
    tmp_reg = Region()
    ep = pya.EdgeProcessor()
    for poly in reg.each():
        tmp_reg.insert(
            ep.simple_merge_p2p([poly.sized(extension, extension, 2)], False,
                                False, 1))
    return tmp_reg
Example #5
0
from math import sin, cos, pi, sqrt, atan2
from load_params import *
import pya

# Create layout and top cell
layout = pya.Layout()
top = layout.create_cell("TOP")


# Rotation transformation
def rotate(theta=360 / n_sides):
    return pya.ICplxTrans(1, theta, False, 0, 0)


# Edge processor
ep = pya.EdgeProcessor()

# Create layers
nemanc = layout.layer(1, 0)
nemchan = layout.layer(2, 0)
nemcont = layout.layer(3, 0)
nembody = layout.layer(4, 0)
nemholes = layout.layer(5, 0)
nemsub = layout.layer(6, 0)
nemsubg = layout.layer(7, 0)
nemland = layout.layer(8, 0)

# Create anchors
ancloc = L_plate / 2 + W_cant + L_anc / 2
ancloc = pya.Point(ancloc, ancloc)
anchor = pya.Box(-L_via / 2, -L_via / 2, L_via / 2, L_via / 2).move(ancloc)
Example #6
0
def make_cpw():

    #Load View
    app = pya.Application.instance()
    mw = app.main_window()
    lv = mw.current_view()
    ly = lv.active_cellview().layout()
    dbu = ly.dbu

    center_radius = 100.0 / dbu  #Curve radius
    center_width = 10. / dbu  #Center conductor width
    s_width = 7. / dbu  #Center - Outer conductor spacing
    keepout_width = center_width * 0.4  #Keepout spacing

    ri = center_radius - .5 * center_width  #Inner radius
    ro = center_radius + .5 * center_width  # Outer radius
    n = 10 / dbu  #Number of points per curve

    cpw_layer = ly.layer(1, 0)
    keepout_layer = ly.layer(1, 6)

    if lv == None:
        raise Exception("No view selected")

    lv.transaction("Make CPW")

    selected_objects = lv.each_object_selected()
    print("x")
    for obj in selected_objects:
        if obj.shape.is_path() and not obj.is_cell_inst():
            inner = pya.Path()
            outer = pya.Path()
            keepout = pya.Path()
            print(obj.shape.path)

            inner = obj.shape.path
            outer = obj.shape.path
            keepout = obj.shape.path

            #Adjust widths
            inner.width = center_width
            outer.width = inner.width + 2 * s_width
            keepout.width = outer.width + 2 * keepout_width

            #Round Corners
            inner = [inner.polygon().round_corners(ri, ro, n)]
            outer = [
                outer.polygon().round_corners(ri - s_width, ro + s_width, n)
            ]
            keepout = keepout.polygon().round_corners(
                ri - s_width - keepout_width, ro + s_width + keepout_width, n)

            #Subtract inner from outer
            ep = pya.EdgeProcessor()
            outer_minus_inner = ep.boolean_p2p(outer, inner,
                                               pya.EdgeProcessor().ModeANotB,
                                               True, False)

            for p in outer_minus_inner:
                lv.active_cellview().cell.shapes(cpw_layer).insert(p)

        # lv.active_cellview().cell.shapes(cpw_layer).insert(outer_minus_inner[0])
            lv.active_cellview().cell.shapes(keepout_layer).insert(keepout)

    lv.commit()