Exemple #1
0
    def test_2_DTrans(self):

        a = pya.DTrans()
        b = pya.DTrans(pya.DTrans.M135, pya.DPoint(17, 5))
        ma = pya.DCplxTrans(a, 0.5)
        mb = pya.DCplxTrans(b, 2.0)
        u = pya.DCplxTrans(a)

        self.assertEqual(str(ma), "r0 *0.5 0,0")
        self.assertEqual(str(mb), "m135 *2 17,5")

        self.assertEqual(ma == mb, False)
        self.assertEqual(ma == ma, True)
        self.assertEqual(ma != mb, True)
        self.assertEqual(ma != ma, False)

        i = mb.inverted()

        self.assertEqual(str(i), "m135 *0.5 2.5,8.5")
        self.assertEqual(str(pya.DCplxTrans.from_s(str(i))), str(i))
        self.assertEqual(i * mb == u, True)
        self.assertEqual(mb * i == u, True)

        self.assertEqual(str(mb.trans(pya.DPoint(1, 0))), "17,3")
        self.assertEqual(str(mb.ctrans(2)), "4.0")
        self.assertEqual(str(i.ctrans(2)), "1.0")
 def tr_back(obj,itr=False):
     trs=[pya.DCplxTrans(1,0,False,-pc.x,-pc.y),
         pya.DCplxTrans(1,deltaangle,False,0,0)]
     if itr:trs=[pya.ICplxTrans.from_dtrans(tr) for tr in trs]
     for tr in trs:
         obj=obj.transformed(tr)
     return obj
 def TurningInterpolation(self, radius):
     #radius非负向右,负是向左
     angle = 90
     delta = self.pointr.distance(self.pointl)
     dx = (self.pointr.x - self.pointl.x) / delta
     dy = (self.pointr.y - self.pointl.y) / delta
     dtheta = atan2(dy, dx) * 180 / pi
     centerx = self.pointr.x + (radius - delta / 2) * dx
     centery = self.pointr.y + (radius - delta / 2) * dy
     n = ceil(1.3 * (abs(radius) + delta / 2) * angle * pi / 180 /
              self.pointdistance) + 2
     if True:
         rsgn = (radius > 0) - (radius < 0)
         pointr2 = pya.DPoint(centerx - rsgn * (radius - delta / 2) * dy,
                              centery + rsgn * (radius - delta / 2) * dx)
         pointl2 = pya.DPoint(centerx - rsgn * (radius + delta / 2) * dy,
                              centery + rsgn * (radius + delta / 2) * dx)
         arc1 = BasicPainter.arc_NewtonInterpolation(
             n,
             abs(radius) + delta / 2,
             abs(radius) - delta / 2)
         trans = pya.DCplxTrans(1, 180 + dtheta + 45 * rsgn, False, centerx,
                                centery)
         arc1.transform(trans)
         self.outputlist.append(arc1)
         self.pointr = pointr2
         self.pointl = pointl2
 def DrawElectrode(x,
                   y,
                   angle,
                   widout=20000,
                   widin=10000,
                   wid=368000,
                   length=360000,
                   midwid=200000,
                   midlength=200000,
                   narrowlength=120000):
     tr = pya.DCplxTrans(1, angle, False, x, y)
     pts = []
     pts.append(pya.DPoint(0, widout / 2))
     pts.append(pya.DPoint(0, widin / 2))
     pts.append(pya.DPoint(narrowlength, midwid / 2))
     pts.append(pya.DPoint(narrowlength + midlength, midwid / 2))
     pts.append(pya.DPoint(narrowlength + midlength, -midwid / 2))
     pts.append(pya.DPoint(narrowlength, -midwid / 2))
     pts.append(pya.DPoint(0, -widin / 2))
     pts.append(pya.DPoint(0, -widout / 2))
     pts.append(pya.DPoint(narrowlength, -wid / 2))
     pts.append(pya.DPoint(length, -wid / 2))
     pts.append(pya.DPoint(length, wid / 2))
     pts.append(pya.DPoint(narrowlength, wid / 2))
     polygon1 = pya.DPolygon(pts).transformed(tr)
     return polygon1, (pya.DPoint(x, y), angle, widout, widin)
Exemple #5
0
 def constructors1(self,
                   pointc=pya.DPoint(0, 0),
                   angle=0,
                   widout=20000,
                   widin=10000,
                   bgn_ext=0):
     tr = pya.DCplxTrans(1, angle, False, pointc)
     self.edgeout = pya.DEdge(0, widout / 2, 0, -widout / 2).transformed(tr)
     self.edgein = pya.DEdge(bgn_ext, widin / 2, bgn_ext,
                             -widin / 2).transformed(tr)
Exemple #6
0
 def Narrow(self,widout,widin,length=6000):
     assert(self.end_ext==0)
     centerx,centery,angle=self.Getinfo()[0:3]
     tr=pya.DCplxTrans(1,angle,False,centerx,centery)
     edgeout=pya.DEdge(length,-widout/2,length,widout/2).transformed(tr)
     edgein=pya.DEdge(length,-widin/2,length,widin/2).transformed(tr)
     self.regionlistout.append(pya.DPolygon([self.painterout.pointl,self.painterout.pointr,edgeout.p1,edgeout.p2]))
     self.regionlistin.append(pya.DPolygon([self.painterin.pointl,self.painterin.pointr,edgein.p1,edgein.p2]))
     self.painterout.Setpoint(edgeout.p1,edgeout.p2)
     self.painterin.Setpoint(edgein.p1,edgein.p2)        
     return length   
Exemple #7
0
 def Connection(x, y=0, angle=0, mod=48):
     if isinstance(x, CavityBrush):
         brush = x
         tr = brush.DCplxTrans
         mod = brush.widout
     else:
         tr = pya.DCplxTrans(1, angle, False, x, y)
     pts = []
     if mod == 48:
         pts.append(pya.DPoint(0, -57000))
         pts.append(pya.DPoint(0, -8000))
         pts.append(pya.DPoint(16000, -8000))
         pts.append(pya.DPoint(16000, -52000))
         pts.append(pya.DPoint(62000, -52000))
         pts.append(pya.DPoint(62000, -32000))
         pts.append(pya.DPoint(32000, -32000))
         pts.append(pya.DPoint(32000, 32000))
         pts.append(pya.DPoint(62000, 32000))
         pts.append(pya.DPoint(62000, 52000))
         pts.append(pya.DPoint(16000, 52000))
         pts.append(pya.DPoint(16000, 8000))
         pts.append(pya.DPoint(0, 8000))
         pts.append(pya.DPoint(0, 57000))
         pts.append(pya.DPoint(67000, 57000))
         pts.append(pya.DPoint(67000, 27000))
         pts.append(pya.DPoint(37000, 27000))
         pts.append(pya.DPoint(37000, -27000))
         pts.append(pya.DPoint(67000, -27000))
         pts.append(pya.DPoint(67000, -57000))
     if mod == 8:
         pts.append(pya.DPoint(0, -57000))
         pts.append(pya.DPoint(0, -2010))
         pts.append(pya.DPoint(224, -2007))
         pts.append(pya.DPoint(2000, -2000))
         pts.append(pya.DPoint(2000, -52000))
         pts.append(pya.DPoint(60000, -52000))
         pts.append(pya.DPoint(60000, -32000))
         pts.append(pya.DPoint(6000, -32000))
         pts.append(pya.DPoint(6000, 32000))
         pts.append(pya.DPoint(60000, 32000))
         pts.append(pya.DPoint(60000, 52000))
         pts.append(pya.DPoint(2000, 52000))
         pts.append(pya.DPoint(2000, 2000))
         pts.append(pya.DPoint(0, 2000))
         pts.append(pya.DPoint(0, 57000))
         pts.append(pya.DPoint(65000, 57000))
         pts.append(pya.DPoint(65000, 27000))
         pts.append(pya.DPoint(11000, 27000))
         pts.append(pya.DPoint(11000, -27000))
         pts.append(pya.DPoint(65000, -27000))
         pts.append(pya.DPoint(65000, -57000))
     polygon1 = pya.DPolygon(pts).transformed(tr)
     return polygon1
Exemple #8
0
 def __init__(self,pointc=pya.DPoint(0,8000),angle=0,widout=20000,widin=10000,bgn_ext=0,end_ext=0):
     self.regionlistout=[]
     self.regionlistin=[]        
     self.path=lambda painter:None
     self.bgn_ext=bgn_ext
     self.end_ext=end_ext
     tr=pya.DCplxTrans(1,angle,False,pointc)
     edgeout=pya.DEdge(0,-widout/2,0,widout/2).transformed(tr)
     edgein=pya.DEdge(bgn_ext,-widin/2,bgn_ext,widin/2).transformed(tr)
     self.painterout=LinePainter(edgeout.p1,edgeout.p2)
     self.painterin=LinePainter(edgein.p1,edgein.p2)
     self.centerlineinfos=[]
Exemple #9
0
    def test_4_Trans(self):

        a = pya.Trans()
        m = pya.CplxTrans(a, 1.1)
        da = pya.DTrans()
        dm = pya.DCplxTrans(da, 1.1)

        self.assertEqual(str(m), "r0 *1.1 0,0")
        self.assertEqual(str(pya.DCplxTrans.from_s(str(m))), str(m))
        self.assertEqual(str(m.trans(pya.Point(5, -7))), "5.5,-7.7")

        im = pya.ICplxTrans(a, 0.5)
        im_old = im.dup()

        self.assertEqual(str(im), "r0 *0.5 0,0")
        self.assertEqual(str(pya.ICplxTrans.from_s(str(im))), str(im))
        self.assertEqual(str(im.trans(pya.Point(5, -7))), "3,-4")

        im = pya.ICplxTrans(m)
        self.assertEqual(str(im), "r0 *1.1 0,0")
        self.assertEqual(str(im.trans(pya.Point(5, -7))), "6,-8")

        im = pya.ICplxTrans(dm)
        self.assertEqual(str(im), "r0 *1.1 0,0")
        self.assertEqual(str(im.trans(pya.Point(5, -7))), "6,-8")

        im.assign(im_old)
        self.assertEqual(str(im), "r0 *0.5 0,0")
        self.assertEqual(str(im.trans(pya.Point(5, -7))), "3,-4")

        self.assertEqual(str(pya.ICplxTrans(5, -7)), "r0 *1 5,-7")

        self.assertEqual(str(pya.ICplxTrans(pya.ICplxTrans.R180, 1.5, 5, -7)),
                         "r180 *1.5 5,-7")
        self.assertEqual(
            str(pya.ICplxTrans(pya.ICplxTrans.R180, 1.5, pya.Point(5, -7))),
            "r180 *1.5 5,-7")
        self.assertEqual(
            str(pya.ICplxTrans(pya.ICplxTrans.R180, 1.5, pya.Vector(5, -7))),
            "r180 *1.5 5,-7")
        self.assertEqual(
            str(pya.ICplxTrans(pya.ICplxTrans.R180, 1.5, pya.DVector(5, -7))),
            "r180 *1.5 5,-7")
        self.assertEqual(str(pya.ICplxTrans(pya.ICplxTrans.R180, 1.5)),
                         "r180 *1.5 0,0")

        c = pya.ICplxTrans.from_dtrans(pya.DCplxTrans.M135)
        self.assertEqual(str(c), "m135 *1 0,0")
        c = pya.ICplxTrans.from_trans(pya.CplxTrans.M135)
        self.assertEqual(str(c), "m135 *1 0,0")
Exemple #10
0
 def Connection(x,y,angle,mod=48):
     tr=pya.DCplxTrans(1,angle,False,x,y)
     pts=[]
     if mod==48:
         pts.append(pya.DPoint(0,-57000))
         pts.append(pya.DPoint(0,-8000))
         pts.append(pya.DPoint(16000,-8000))
         pts.append(pya.DPoint(16000,-52000))
         pts.append(pya.DPoint(62000,-52000))
         pts.append(pya.DPoint(62000,-32000))
         pts.append(pya.DPoint(32000,-32000))
         pts.append(pya.DPoint(32000,32000))
         pts.append(pya.DPoint(62000,32000))
         pts.append(pya.DPoint(62000,52000))
         pts.append(pya.DPoint(16000,52000))
         pts.append(pya.DPoint(16000,8000))
         pts.append(pya.DPoint(0,8000))
         pts.append(pya.DPoint(0,57000))
         pts.append(pya.DPoint(67000,57000))
         pts.append(pya.DPoint(67000,27000))
         pts.append(pya.DPoint(37000,27000))
         pts.append(pya.DPoint(37000,-27000))
         pts.append(pya.DPoint(67000,-27000))
         pts.append(pya.DPoint(67000,-57000))
     if mod==8:
         pts.append(pya.DPoint(0,-57000))
         pts.append(pya.DPoint(0,-2010))
         pts.append(pya.DPoint(224,-2007))
         pts.append(pya.DPoint(2000,-2000))
         pts.append(pya.DPoint(2000,-52000))
         pts.append(pya.DPoint(60000,-52000))
         pts.append(pya.DPoint(60000,-32000))
         pts.append(pya.DPoint(6000,-32000))
         pts.append(pya.DPoint(6000,32000))
         pts.append(pya.DPoint(60000,32000))
         pts.append(pya.DPoint(60000,52000))
         pts.append(pya.DPoint(2000,52000))
         pts.append(pya.DPoint(2000,2000))
         pts.append(pya.DPoint(0,2000))
         pts.append(pya.DPoint(0,57000))
         pts.append(pya.DPoint(65000,57000))
         pts.append(pya.DPoint(65000,27000))
         pts.append(pya.DPoint(11000,27000))
         pts.append(pya.DPoint(11000,-27000))
         pts.append(pya.DPoint(65000,-27000))
         pts.append(pya.DPoint(65000,-57000))
     polygon1=pya.DPolygon(pts).transformed(tr)
     return polygon1
Exemple #11
0
    def scanBoxes(cellList=None,
                  layerList=None,
                  layermod='in',
                  position='leftdown'):
        if cellList == None: cellList = [IO.top]
        if layerList == None: layerList = [(0, 1)]
        _layerlist = []
        for ii in layerList:
            if type(ii) == str:
                if IO.layout.find_layer(ii) != None:
                    _layerlist.append(IO.layout.find_layer(ii))
            else:
                if IO.layout.find_layer(ii[0], ii[1]) != None:
                    _layerlist.append(IO.layout.find_layer(ii[0], ii[1]))
        layers = [
            index for index in IO.layout.layer_indices() if index in _layerlist
        ] if layermod == 'in' else [
            index for index in IO.layout.layer_indices()
            if index not in _layerlist
        ]

        region = pya.Region()
        for cell in cellList:
            for layer in layers:
                s = cell.begin_shapes_rec(layer)
                region.insert(s)
        region.merge()
        pts = []
        for polygon in region.each():
            print(polygon)
            try:
                polygon = polygon.bbox()
            finally:
                pass
            print(polygon)
            pt = polygon.p1 if position == 'leftdown' else polygon.center()
            pts.append(pt)
        output = []
        layer = IO.layout.layer(0, 2)
        cell = IO.layout.create_cell("boxMarks")
        IO.auxiliary.insert(pya.CellInstArray(cell.cell_index(), pya.Trans()))
        painter = PcellPainter()
        for index, pt in enumerate(pts, 1):
            name = "M" + str(index)
            painter.DrawText(cell, layer, name,
                             pya.DCplxTrans(100, 0, False, pt.x, pt.y))
            output.append([name, {"x": pt.x, "y": pt.y}])
        return output
Exemple #12
0
 def TurningInterpolation(self, radius, angle=90):  #有待改进
     #radius非负向右,负是向左
     pass
     if angle < 0:
         angle = -angle
         radius = -radius
     angle = 90
     delta = self.pointr.distance(self.pointl)
     dx = (self.pointr.x - self.pointl.x) / delta
     dy = (self.pointr.y - self.pointl.y) / delta
     dtheta = atan2(dy, dx) * 180 / pi
     centerx = self.pointr.x + (radius - delta / 2) * dx
     centery = self.pointr.y + (radius - delta / 2) * dy
     n = int(
         ceil(1.3 * (abs(radius) + delta / 2) * angle * pi / 180 /
              IO.pointdistance) + 2)
     #
     rsgn = (radius > 0) - (radius < 0)
     pointr2 = pya.DPoint(centerx - rsgn * (radius - delta / 2) * dy,
                          centery + rsgn * (radius - delta / 2) * dx)
     pointl2 = pya.DPoint(centerx - rsgn * (radius + delta / 2) * dy,
                          centery + rsgn * (radius + delta / 2) * dx)
     pts1 = BasicPainter.arc_NewtonInterpolation(n, abs(radius) + delta / 2)
     pts2 = BasicPainter.arc_NewtonInterpolation(n, abs(radius) - delta / 2)
     pts1.extend(reversed(pts2))
     arc1 = pya.DPolygon(pts1)
     trans = pya.DCplxTrans(1, 180 + dtheta + 45 * rsgn, False, centerx,
                            centery)
     arc1.transform(trans)
     self.outputlist.append(arc1)
     self.pointr = pointr2
     self.pointl = pointl2
     pts3 = BasicPainter.arc_NewtonInterpolation(n, abs(radius))
     cpts = [
         pya.DEdge(pya.DPoint(), pt).transformed(trans).p2 for pt in pts3
     ]
     if abs(cpts[-1].distance(self.pointr) - delta / 2) < IO.pointdistance:
         if self.centerlinepts == []:
             self.centerlinepts = cpts
         else:
             self.centerlinepts.extend(cpts[1:])
     else:
         if self.centerlinepts == []:
             self.centerlinepts = cpts[::-1]
         else:
             self.centerlinepts.extend(cpts[-2::-1])
     return pi * 0.5 * abs(radius)
Exemple #13
0
    def test_5_CplxTrans_Hash(self):

        t1 = pya.DCplxTrans(pya.DTrans(pya.DTrans.M135, pya.DPoint(17, 5)),
                            1.0)
        t2a = pya.DCplxTrans(
            pya.DTrans(pya.DTrans.M135, pya.DPoint(17 + 1e-7, 5)), 1.0)
        t2b = pya.DCplxTrans(pya.DTrans(pya.DTrans.M135, pya.DPoint(17, 5)),
                             1.0 + 1e-11)
        t2c = pya.DCplxTrans(pya.DTrans(pya.DTrans.M135, pya.DPoint(17, 5)),
                             1.0)
        t2c.angle = t2c.angle + 1e-11
        t3a = pya.DCplxTrans(
            pya.DTrans(pya.DTrans.M135, pya.DPoint(17 + 1e-4, 5)), 1.0)
        t3b = pya.DCplxTrans(pya.DTrans(pya.DTrans.M135, pya.DPoint(17, 5)),
                             1.0 + 1e-4)
        t3c = pya.DCplxTrans(pya.DTrans(pya.DTrans.M135, pya.DPoint(17, 5)),
                             1.0)
        t3c.angle = t3c.angle + 1e-4
        t4 = pya.DCplxTrans(pya.DTrans(pya.DTrans.R90, pya.DPoint(18, 5)), 1.0)

        self.assertEqual(t1.hash() == t2a.hash(), True)
        self.assertEqual(t1.hash() == t2b.hash(), True)
        self.assertEqual(t1.hash() == t2c.hash(), True)
        self.assertEqual(t1.hash() == t3a.hash(), False)
        self.assertEqual(t1.hash() == t3b.hash(), False)
        self.assertEqual(t1.hash() == t3c.hash(), False)
        self.assertEqual(t3a.hash() == t3b.hash(), False)
        self.assertEqual(t3a.hash() == t3c.hash(), False)
        self.assertEqual(t3b.hash() == t3c.hash(), False)
        self.assertEqual(t1.hash() == t4.hash(), False)

        # Transformations can't be used as hash keys currently
        if False:

            h = {t1: "t1", t3a: "t3a", t3b: "t3b", t3c: "t3c", t4: "t4"}

            self.assertEqual(h[t1], "t1")
            self.assertEqual(h[t2a], "t1")
            self.assertEqual(h[t2b], "t1")
            self.assertEqual(h[t2c], "t1")
            self.assertEqual(h[t3a], "t3a")
            self.assertEqual(h[t3b], "t3b")
            self.assertEqual(h[t3c], "t3c")
            self.assertEqual(h[t4], "t4")
Exemple #14
0
 def Connection(x,
                widin=16000,
                widout=114000,
                linewid=5000,
                slength1=16000,
                slength2=16000,
                clength=30000,
                cwid=54000,
                y=0,
                angle=0):
     if isinstance(x, CavityBrush):
         brush = x
         tr = brush.DCplxTrans
     else:
         tr = pya.DCplxTrans(1, angle, False, x, y)
     pts = [
         pya.DPoint(0, widin / 2),
         pya.DPoint(slength1, widin / 2),
         pya.DPoint(slength1, widout / 2 - linewid),
         pya.DPoint(slength1 + slength2 + clength, widout / 2 - linewid),
         pya.DPoint(slength1 + slength2 + clength, cwid / 2 + linewid),
         pya.DPoint(slength1 + slength2, cwid / 2 + linewid),
         #
         pya.DPoint(slength1 + slength2, -(cwid / 2 + linewid)),
         pya.DPoint(slength1 + slength2 + clength, -(cwid / 2 + linewid)),
         pya.DPoint(slength1 + slength2 + clength, -(widout / 2 - linewid)),
         pya.DPoint(slength1, -(widout / 2 - linewid)),
         pya.DPoint(slength1, -widin / 2),
         pya.DPoint(0, -widin / 2),
         #
         pya.DPoint(0, -widout / 2),
         pya.DPoint(slength1 + slength2 + clength + linewid, -widout / 2),
         pya.DPoint(slength1 + slength2 + clength + linewid, -cwid / 2),
         pya.DPoint(slength1 + slength2 + linewid, -cwid / 2),
         #
         pya.DPoint(slength1 + slength2 + linewid, cwid / 2),
         pya.DPoint(slength1 + slength2 + clength + linewid, cwid / 2),
         pya.DPoint(slength1 + slength2 + clength + linewid, widout / 2),
         pya.DPoint(0, widout / 2),
     ]
     polygon1 = pya.DPolygon(pts).transformed(tr)
     return polygon1
Exemple #15
0
    def move(self,
             x: float = 0,
             y: float = 0,
             rot: int = 0,
             mirrx: bool = False,
             mag: float = 1):
        """Moves an instance. Units of microns relative to origin.

        :param x: x position where to move
        :type x: float
        :param y: y position where to move
        :type y: float
        :param rot: Rotation of the object in degrees
        :type rot: int
        :param mirrx: Mirror at x-axis if True
        :type mirrx: bool
        :param mag: Magnification of the Cell. This feature is not tested well.
        :type mag: float
        """
        if self.connection:
            raise ValueError(
                'Cannot connect to a port of another instance and move the same instance. These operations are mutually exlusive'
            )
        self.movement = pya.DCplxTrans(mag, rot, mirrx, x, y)
Exemple #16
0
]
polygon1 = pya.Polygon(pts)
top.shapes(l1).insert(polygon1)
#DPath
dpts = [
    pya.DPoint(0.4, 0),
    pya.DPoint(50, 0),
    pya.DPoint(50, 50),
    pya.DPoint(40.5, 60.6),
    pya.DPoint(0, 50)
]
dpath1 = pya.DPath(dpts, 4, 5, 0, True)
top.shapes(l1).insert(pya.Path.from_dpath(dpath1))
#DCplxTrans
#倍数,逆时针度数,是否绕x翻转,平移x,平移y
tr = pya.DCplxTrans(10, 45, False, 1000, 1000)
#xxx.transform(tr)#本身改变
#xxx.transformed(tr)本身不变返回新的
#对一个点pt做变换的方法
#pya.DEdge(pya.DPoint(),pt).transformed(DCplxTrans).p2

#DText
text1 = pya.DText("TEST_Text", pya.DTrans(-10, -10), 100, 1)
top.shapes(l1).insert(pya.Text.from_dtext(text1))
#a text can be printed @ruby
#it dose not work in python
#lib.layout.pcell_declaration can't be found
'''
begin
ly = RBA::Layout.new
 top = ly.add_cell("TOP")
Exemple #17
0
  def test_1_DPolygon(self):

    a = pya.DPolygon()
    self.assertEqual( str(a), "()" )
    self.assertEqual( str(pya.DPolygon.from_s(str(a))), str(a) )
    self.assertEqual( a.is_box(), False )

    b = a.dup()
    a = pya.DPolygon( [ pya.DPoint( 0, 1 ), pya.DPoint( 1, 5 ), pya.DPoint( 5, 5 ) ] )
    self.assertEqual( str(a), "(0,1;1,5;5,5)" )
    self.assertEqual( str(a * 2), "(0,2;2,10;10,10)" )
    self.assertEqual( str(pya.DPolygon.from_s(str(a))), str(a) )
    self.assertEqual( a.is_box(), False )
    self.assertEqual( a.num_points_hull(), 3 )
    c = a.dup()

    self.assertEqual( a == b, False )
    self.assertEqual( a == c, True )
    self.assertEqual( a != b, True )
    self.assertEqual( a != c, False )

    a = pya.DPolygon( pya.DBox( 5, -10, 20, 15 ) )
    self.assertEqual( a.is_box(), True )
    self.assertEqual( str(a), "(5,-10;5,15;20,15;20,-10)" )
    self.assertEqual( str(pya.Polygon(a)), "(5,-10;5,15;20,15;20,-10)" )
    self.assertEqual( a.num_points_hull(), 4 )
    self.assertEqual( a.area(), 15*25 )
    self.assertEqual( a.perimeter(), 80 )
    self.assertEqual( a.inside( pya.DPoint( 10, 0 ) ), True )
    self.assertEqual( a.inside( pya.DPoint( 5, 0 ) ), True )
    self.assertEqual( a.inside( pya.DPoint( 30, 0 ) ), False )

    arr = []
    for p in a.each_point_hull():
      arr.append( str(p) )
    self.assertEqual( arr, ["5,-10", "5,15", "20,15", "20,-10"] )

    b = a.dup()

    self.assertEqual( str(a.moved( pya.DPoint( 0, 1 ) )), "(5,-9;5,16;20,16;20,-9)" )
    self.assertEqual( str(a.moved( 0, 1 )), "(5,-9;5,16;20,16;20,-9)" )
    aa = a.dup()
    aa.move( 1, 0 )
    self.assertEqual( str(aa), "(6,-10;6,15;21,15;21,-10)" )
    a.move( pya.DPoint( 1, 0 ) )
    self.assertEqual( str(a), "(6,-10;6,15;21,15;21,-10)" )

    b = b.transformed( pya.DTrans( pya.DTrans.R0, pya.DPoint( 1, 0 )) )
    self.assertEqual( str(b), "(6,-10;6,15;21,15;21,-10)" )

    m = pya.DCplxTrans( pya.DTrans(), 1.5 )
    self.assertEqual( type(a.transformed(m)).__name__, "DPolygon" )
    self.assertEqual( str(a.transformed(m)), "(9,-15;9,22.5;31.5,22.5;31.5,-15)" )

    m = pya.VCplxTrans( 1000.0 )
    self.assertEqual( type(a.transformed(m)).__name__, "Polygon" )
    self.assertEqual( str(a.transformed(m)), "(6000,-10000;6000,15000;21000,15000;21000,-10000)" )

    a.hull = [ pya.DPoint( 0, 1 ), pya.DPoint( 1, 1 ), pya.DPoint( 1, 5 ) ]
    self.assertEqual( str(a.bbox()), "(0,1;1,5)" )

    self.assertEqual( a.holes(), 0 )
    a.insert_hole( [ pya.DPoint( 1, 2 ), pya.DPoint( 2, 2 ), pya.DPoint( 2, 6 ) ] )
    self.assertEqual( str(a), "(0,1;1,5;1,1/1,2;2,2;2,6)" )
    self.assertEqual( str(pya.DPolygon.from_s(str(a))), str(a) )
    self.assertEqual( a.area(), 0 )
    self.assertEqual( a.num_points_hole(0), 3 )
    self.assertEqual( a.holes(), 1 )
    self.assertEqual( str(a.point_hull(1)), "1,5" )
    self.assertEqual( str(a.point_hull(0)), "0,1" )
    self.assertEqual( str(a.point_hull(100)), "0,0" )
    self.assertEqual( str(a.point_hole(0, 100)), "0,0" )
    self.assertEqual( str(a.point_hole(0, 1)), "2,2" )
    self.assertEqual( str(a.point_hole(1, 1)), "0,0" )
    a.compress(False);
    self.assertEqual( str(a), "(0,1;1,5;1,1/1,2;2,2;2,6)" )
    a.compress(True);
    self.assertEqual( str(a), "(0,1;1,5;1,1/1,2;2,2;2,6)" )

    b = a.dup()
    b.assign_hole(0, pya.DBox( 10, 20, 20, 60 ))
    self.assertEqual( str(b), "(0,1;1,5;1,1/10,20;20,20;20,60;10,60)" )
    b.insert_hole(pya.DBox( 10, 20, 20, 60 ))
    self.assertEqual( str(b), "(0,1;1,5;1,1/10,20;20,20;20,60;10,60/10,20;20,20;20,60;10,60)" )
    self.assertEqual( b.is_box(), False )

    b = a.dup()
    b.assign_hole(0, [ pya.DPoint( 10, 20 ), pya.DPoint( 20, 20 ), pya.DPoint( 20, 60 ) ])
    self.assertEqual( str(b), "(0,1;1,5;1,1/10,20;20,20;20,60)" )
    b.assign_hole(1, [ pya.DPoint( 15, 25 ), pya.DPoint( 25, 25 ), pya.DPoint( 25, 65 ) ])
    self.assertEqual( str(b), "(0,1;1,5;1,1/10,20;20,20;20,60)" )
    b.insert_hole( [ pya.DPoint( 1, 2 ), pya.DPoint( 2, 2 ), pya.DPoint( 2, 6 ) ] )
    self.assertEqual( str(b), "(0,1;1,5;1,1/1,2;2,2;2,6/10,20;20,20;20,60)" )
    b.assign_hole(0, [ pya.DPoint( 15, 25 ), pya.DPoint( 25, 25 ), pya.DPoint( 25, 65 ) ])
    self.assertEqual( str(b), "(0,1;1,5;1,1/15,25;25,25;25,65/10,20;20,20;20,60)" )

    arr = []
    for p in a.each_point_hole(0):
      arr.append( str(p) )

    self.assertEqual( arr, ["1,2", "2,2", "2,6"] )

    arr = []
    for p in a.each_edge():
      arr.append( str(p) )
    self.assertEqual( arr, ["(0,1;1,5)", "(1,5;1,1)", "(1,1;0,1)", "(1,2;2,2)", "(2,2;2,6)", "(2,6;1,2)"] )

    # Ellipse constructor
    p = pya.DPolygon.ellipse( pya.DBox(-10000, -20000, 30000, 40000), 200 )
    self.assertEqual(p.num_points(), 200)
    self.assertEqual(str(p.bbox()), "(-10000,-20000;30000,40000)")
    self.assertEqual(int(p.area()), 1884645544)    # roughly box.area*PI/4
    
    p = pya.DPolygon.ellipse( pya.DBox(-10000, -20000, 30000, 40000), 4 )
    self.assertEqual(str(p), "(10000,-20000;-10000,10000;10000,40000;30000,10000)")
    def Connection(x,
                   widin=16000,
                   widout=114000,
                   linewid=5000,
                   slength1=16000,
                   slength2=16000,
                   clength=30000,
                   cwid=54000,
                   clengthplus=0,
                   turningRadiusPlus=5000,
                   y=0,
                   angle=0):
        ''' 画腔到比特的连接(更复杂的版本),第一个参数是笔刷或坐标,返回图形 '''
        if isinstance(x, CavityBrush):
            brush = x
            tr = brush.DCplxTrans
        else:
            tr = pya.DCplxTrans(1, angle, False, x, y)
        oldpointdistance = IO.pointdistance
        IO.pointdistance = max(100, int(IO.pointdistance / 10))
        try:
            rp = turningRadiusPlus
            r = turningRadiusPlus + linewid / 2
            polygons = []
            pts = [
                pya.DPoint(0, widin / 2),
                pya.DPoint(slength1, widin / 2),
                pya.DPoint(slength1, widout / 2),
                pya.DPoint(0, widout / 2),
            ]
            polygons.append(pya.DPolygon(pts))
            pts = [
                pya.DPoint(0, -widin / 2),
                pya.DPoint(slength1, -widin / 2),
                pya.DPoint(slength1, -widout / 2),
                pya.DPoint(0, -widout / 2),
            ]
            polygons.append(pya.DPolygon(pts))
            dx = widout / 2 - cwid / 2 - 2 * linewid
            tangle = 90 - atan2(clengthplus, dx) * 180 / pi
            lp = LinePainter(pointl=pya.DPoint(slength1, widout / 2),
                             pointr=pya.DPoint(slength1, widout / 2 - linewid))
            #
            lp._Straight(-1)
            lp._Straight(1)
            #
            lp.Straight(slength2 + clength - rp * tan(tangle / 2 * pi / 180))
            lp.Turning(r, tangle)
            lp.Straight(-rp * tan(tangle / 2 * pi / 180) +
                        dx / sin(tangle * pi / 180) -
                        rp / tan(tangle / 2 * pi / 180))
            lp.Turning(r, 180 - tangle)
            lp.Straight(-rp / tan(tangle / 2 * pi / 180) + clengthplus +
                        clength - linewid)
            #
            lp.Turning(-linewid / 2, 90)
            lp._Straight(-linewid)
            lp.Straight(linewid + cwid)
            lp.Turning(-linewid / 2, 90)
            lp._Straight(-linewid)
            lp.Straight(linewid)
            #
            lp.Straight(-rp / tan(tangle / 2 * pi / 180) + clengthplus +
                        clength - linewid)
            lp.Turning(r, 180 - tangle)
            lp.Straight(-rp * tan(tangle / 2 * pi / 180) +
                        dx / sin(tangle * pi / 180) -
                        rp / tan(tangle / 2 * pi / 180))
            lp.Turning(r, tangle)
            lp.Straight(slength2 + clength - rp * tan(tangle / 2 * pi / 180))
            #
            lp._Straight(1)
            lp._Straight(-1)
            #
            polygons.extend(lp.outputlist)
        except:
            raise
        finally:
            IO.pointdistance = oldpointdistance

        return [p.transformed(tr) for p in polygons]
Exemple #19
0
    def test_5_CplxTrans_FuzzyCompare(self):

        t1 = pya.DCplxTrans(pya.DTrans(pya.DTrans.M135, pya.DPoint(17, 5)),
                            1.0)
        t2a = pya.DCplxTrans(
            pya.DTrans(pya.DTrans.M135, pya.DPoint(17 + 1e-7, 5)), 1.0)
        t2b = pya.DCplxTrans(pya.DTrans(pya.DTrans.M135, pya.DPoint(17, 5)),
                             1.0 + 1e-11)
        t2c = pya.DCplxTrans(pya.DTrans(pya.DTrans.M135, pya.DPoint(17, 5)),
                             1.0)
        t2c.angle = t2c.angle + 1e-11
        t3a = pya.DCplxTrans(
            pya.DTrans(pya.DTrans.M135, pya.DPoint(17 + 1e-4, 5)), 1.0)
        t3b = pya.DCplxTrans(pya.DTrans(pya.DTrans.M135, pya.DPoint(17, 5)),
                             1.0 + 1e-4)
        t3c = pya.DCplxTrans(pya.DTrans(pya.DTrans.M135, pya.DPoint(17, 5)),
                             1.0)
        t3c.angle = t3c.angle + 1e-4
        t4 = pya.DCplxTrans(pya.DTrans(pya.DTrans.R90, pya.DPoint(18, 5)), 1.0)

        self.assertEqual(t1 == t2a, True)
        self.assertEqual(t1 != t2a, False)
        self.assertEqual(t1 < t2a, False)
        self.assertEqual(t2a < t1, False)

        self.assertEqual(t1 == t2b, True)
        self.assertEqual(t1 != t2b, False)
        self.assertEqual(t1 < t2b, False)
        self.assertEqual(t2b < t1, False)

        self.assertEqual(t1 == t2c, True)
        self.assertEqual(t1 != t2c, False)
        self.assertEqual(t1 < t2c, False)
        self.assertEqual(t2c < t1, False)

        self.assertEqual(t1 == t3a, False)
        self.assertEqual(t1 != t3a, True)
        self.assertEqual(t1 < t3a, True)
        self.assertEqual(t3a < t1, False)

        self.assertEqual(t1 == t3b, False)
        self.assertEqual(t1 != t3b, True)
        self.assertEqual(t1 < t3b, False)
        self.assertEqual(t3b < t1, True)

        self.assertEqual(t1 == t3c, False)
        self.assertEqual(t1 != t3c, True)
        self.assertEqual(t1 < t3c, True)
        self.assertEqual(t3c < t1, False)

        self.assertEqual(t3a == t3b, False)
        self.assertEqual(t3a != t3b, True)
        self.assertEqual(t3a < t3b, False)
        self.assertEqual(t3b < t3a, True)

        self.assertEqual(t3a == t3c, False)
        self.assertEqual(t3a != t3c, True)
        self.assertEqual(t3a < t3c, False)
        self.assertEqual(t3c < t3a, True)

        self.assertEqual(t3b == t3c, False)
        self.assertEqual(t3b != t3c, True)
        self.assertEqual(t3b < t3c, True)
        self.assertEqual(t3c < t3b, False)

        self.assertEqual(t1 == t4, False)
        self.assertEqual(t1 != t4, True)
        self.assertEqual(t1 < t4, True)
        self.assertEqual(t4 < t1, False)
Exemple #20
0
    width = 8000
    height = 28000
    filename = 'abc.gds'
    outputfile = ''

if noguitest:
    layout, top = paintlib.IO.Start("gds")
else:
    layout, top = paintlib.IO.Start("guiopen")
layout.dbu = 0.001  # 设置单位长度为1nm
paintlib.IO.pointdistance = 1000
paintlib.IO.SetWoringDir(__file__)

if noguitest:
    painter = paintlib.TransfilePainter(filename=filename)
    painter.DrawGds(top, 'sourcefile', pya.DCplxTrans())


def extractABFromGDS(sourceLayerList=[(2, 0)]):
    output = []
    layers = paintlib.Collision.getLayers(layerList=sourceLayerList,
                                          layermod='in')
    for layer in layers:
        it = paintlib.IO.top.begin_shapes_rec(layer)
        while not it.at_end():
            shape_ = it.shape()
            area_ = shape_.area()

            if width * height * 0.98 < area_ < width * height * 1.02:
                # return shape_
                r = dict(
Exemple #21
0
    def test_3_DTrans(self):

        c = pya.DCplxTrans(5.0, -7.0)
        self.assertEqual(str(c), "r0 *1 5,-7")

        c = pya.DCplxTrans(pya.DCplxTrans.M135)
        self.assertEqual(str(c), "m135 *1 0,0")
        self.assertEqual(c.is_unity(), False)
        self.assertEqual(c.is_ortho(), True)
        self.assertEqual(c.is_mag(), False)
        self.assertEqual(c.is_mirror(), True)
        self.assertEqual(c.rot(), pya.DCplxTrans.M135.rot())
        self.assertEqual(str(c.s_trans()), "m135 0,0")
        self.assertAlmostEqual(c.angle, 270)

        self.assertEqual(str(c.trans(pya.DEdge(0, 1, 2, 3))), "(-3,-2;-1,0)")
        self.assertEqual(str((c * pya.DEdge(0, 1, 2, 3))), "(-3,-2;-1,0)")
        self.assertEqual(str(c.trans(pya.DBox(0, 1, 2, 3))), "(-3,-2;-1,0)")
        self.assertEqual(str((c * pya.DBox(0, 1, 2, 3))), "(-3,-2;-1,0)")
        self.assertEqual(str(c.trans(pya.DText("text", pya.DVector(0, 1)))),
                         "('text',m135 -1,0)")
        self.assertEqual(str((c * pya.DText("text", pya.DVector(0, 1)))),
                         "('text',m135 -1,0)")
        self.assertEqual(
            str(
                c.trans(
                    pya.DPolygon([
                        pya.DPoint(0, 1),
                        pya.DPoint(2, -3),
                        pya.DPoint(4, 5)
                    ]))), "(-5,-4;-1,0;3,-2)")
        self.assertEqual(
            str((c * pya.DPolygon(
                [pya.DPoint(0, 1),
                 pya.DPoint(2, -3),
                 pya.DPoint(4, 5)]))), "(-5,-4;-1,0;3,-2)")
        self.assertEqual(
            str(c.trans(pya.DPath(
                [pya.DPoint(0, 1), pya.DPoint(2, 3)], 10))),
            "(-1,0;-3,-2) w=10 bx=0 ex=0 r=false")
        self.assertEqual(
            str((c * pya.DPath(
                [pya.DPoint(0, 1), pya.DPoint(2, 3)], 10))),
            "(-1,0;-3,-2) w=10 bx=0 ex=0 r=false")

        c = pya.DCplxTrans.from_itrans(pya.CplxTrans.M135)
        self.assertEqual(str(c), "m135 *1 0,0")

        c = pya.DCplxTrans(1.5)
        self.assertEqual(str(c), "r0 *1.5 0,0")
        self.assertEqual(c.is_unity(), False)
        self.assertEqual(c.is_ortho(), True)
        self.assertEqual(c.is_mag(), True)
        self.assertEqual(c.is_mirror(), False)
        self.assertEqual(c.rot(), pya.DCplxTrans.R0.rot())
        self.assertEqual(str(c.s_trans()), "r0 0,0")
        self.assertAlmostEqual(c.angle, 0)

        c = pya.DCplxTrans(0.75, 45, True, 2.5, -12.5)
        self.assertEqual(str(c), "m22.5 *0.75 2.5,-12.5")
        c = pya.DCplxTrans(0.75, 45, True, pya.DPoint(2.5, -12.5))
        self.assertEqual(str(c), "m22.5 *0.75 2.5,-12.5")
        self.assertEqual(c.is_unity(), False)
        self.assertEqual(c.is_ortho(), False)
        self.assertEqual(c.is_mag(), True)
        self.assertEqual(c.rot(), pya.DCplxTrans.M0.rot())
        self.assertEqual(str(c.s_trans()), "m0 2.5,-12.5")
        self.assertAlmostEqual(c.angle, 45)

        self.assertEqual(str(c.ctrans(5)), "3.75")
        self.assertEqual(str(c.trans(pya.DPoint(12, 16))),
                         "17.3492424049,-14.6213203436")

        self.assertEqual(str(pya.DCplxTrans()), "r0 *1 0,0")
        self.assertEqual(pya.DCplxTrans().is_unity(), True)
        self.assertEqual((c * c.inverted()).is_unity(), True)

        c.mirror = False
        self.assertEqual(str(c), "r45 *0.75 2.5,-12.5")
        c.mag = 1.5
        self.assertEqual(str(c), "r45 *1.5 2.5,-12.5")
        c.disp = pya.DPoint(-1.0, 5.5)
        self.assertEqual(str(c), "r45 *1.5 -1,5.5")
        self.assertEqual(c.mag, 1.5)
        c.angle = 60
        self.assertEqual(str(c), "r60 *1.5 -1,5.5")
        self.assertEqual(("%g" % c.angle), "60")

        # Constructor variations
        self.assertEqual(str(pya.ICplxTrans()), "r0 *1 0,0")
        self.assertEqual(str(pya.ICplxTrans(1.5)), "r0 *1.5 0,0")
        self.assertEqual(str(pya.ICplxTrans(pya.Trans(1, False, 10, 20), 1.5)),
                         "r90 *1.5 10,20")
        self.assertEqual(str(pya.ICplxTrans(pya.Trans(1, False, 10, 20))),
                         "r90 *1 10,20")
        self.assertEqual(
            str(pya.ICplxTrans(1.5, 80, True, pya.Vector(100, 200))),
            "m40 *1.5 100,200")
        self.assertEqual(str(pya.ICplxTrans(1.5, 80, True, 100, 200)),
                         "m40 *1.5 100,200")
        self.assertEqual(str(pya.ICplxTrans(pya.Vector(100, 200))),
                         "r0 *1 100,200")
        self.assertEqual(str(pya.ICplxTrans(100, 200)), "r0 *1 100,200")
        self.assertEqual(str(pya.ICplxTrans(pya.ICplxTrans(100, 200))),
                         "r0 *1 100,200")
        self.assertEqual(str(pya.ICplxTrans(pya.ICplxTrans(100, 200), 1.5)),
                         "r0 *1.5 150,300")
        self.assertEqual(
            str(
                pya.ICplxTrans(pya.ICplxTrans(100, 200), 1.5,
                               pya.Vector(10, 20))), "r0 *1.5 160,320")
        self.assertEqual(
            str(pya.ICplxTrans(pya.ICplxTrans(100, 200), 1.5, 10, 20)),
            "r0 *1.5 160,320")

        self.assertEqual(str(pya.DCplxTrans()), "r0 *1 0,0")
        self.assertEqual(str(pya.DCplxTrans(1.5)), "r0 *1.5 0,0")
        self.assertEqual(
            str(pya.DCplxTrans(pya.DTrans(1, False, 0.01, 0.02), 1.5)),
            "r90 *1.5 0.01,0.02")
        self.assertEqual(str(pya.DCplxTrans(pya.DTrans(1, False, 0.01, 0.02))),
                         "r90 *1 0.01,0.02")
        self.assertEqual(
            str(pya.DCplxTrans(1.5, 80, True, pya.DVector(0.1, 0.2))),
            "m40 *1.5 0.1,0.2")
        self.assertEqual(str(pya.DCplxTrans(1.5, 80, True, 0.1, 0.2)),
                         "m40 *1.5 0.1,0.2")
        self.assertEqual(str(pya.DCplxTrans(pya.DVector(0.1, 0.2))),
                         "r0 *1 0.1,0.2")
        self.assertEqual(str(pya.DCplxTrans(0.1, 0.2)), "r0 *1 0.1,0.2")
        self.assertEqual(str(pya.DCplxTrans(pya.DCplxTrans(0.1, 0.2))),
                         "r0 *1 0.1,0.2")
        self.assertEqual(str(pya.DCplxTrans(pya.DCplxTrans(0.1, 0.2), 1.5)),
                         "r0 *1.5 0.15,0.3")
        self.assertEqual(
            str(
                pya.DCplxTrans(pya.DCplxTrans(0.1, 0.2), 1.5,
                               pya.DVector(0.01, 0.02))), "r0 *1.5 0.16,0.32")
        self.assertEqual(
            str(pya.DCplxTrans(pya.DCplxTrans(0.1, 0.2), 1.5, 0.01, 0.02)),
            "r0 *1.5 0.16,0.32")
import paintlib

layout, top = paintlib.IO.Start("guinew")  # 在当前的图上继续画,如果没有就创建一个新的
layout.dbu = 0.001  # 设置单位长度为1nm
paintlib.IO.pointdistance = 1000  # 设置腔的精度,转弯处相邻两点的距离
paintlib.IO.SetWoringDir(__file__)
TBD = paintlib.TBD.init(6876587)
filepath = paintlib.IO.path + '/demos/'

# %%
layer = layout.layer(10, 10)
layer1 = layout.layer(10, 3)
layer2 = layout.layer(10, 2)

painter6 = paintlib.TransfilePainter(filepath + "CascadeRoutePaths.gds")
tr = pya.DCplxTrans(1, 0, False, 0, 0)
painter6.DrawGds(top, "layout0", tr)

cell = layout.create_cell("border")
top.insert(pya.CellInstArray(cell.cell_index(), pya.Trans(0, 400000)))

border = paintlib.BasicPainter.Border(leng=4550000, siz=4550000, wed=50000)
paintlib.BasicPainter.Draw(cell, layout.layer(0, 3), border)

cell = layout.create_cell("lines")
top.insert(pya.CellInstArray(cell.cell_index(), pya.Trans()))

inputs = [{
    "section": "Filter1",
    "PositionIn": [-2647, 3324, 180, "5105"],
    "PositionOut": [0, 3310, 90, "5105"]
Exemple #23
0
    layer1,
    paintlib.CavityBrush(pointc=pya.DPoint(800000, -70000),
                         angle=0,
                         widout=24000,
                         widin=8000,
                         bgn_ext=0),
    xfunc,
    yfunc,
    pointnumber=100,
    startlength=10000,
    deltalength=100000,
    number=10,
    lengthlist=[50000, 40000, 5000, 40000, 20000])
paintlib.PcellPainter().DrawText(cell5, layer2,
                                 "y=10*x*(x-0.333)*(x-0.6666)*(x-1)",
                                 pya.DCplxTrans(30, 25, False, 800000, 0))
#


def getSpiralFunc(a, angle0, angle1):
    from math import cos, sin, pi, sqrt

    def f(t):
        return (angle0 * (1 - t) + angle1 * t) / 180 * pi

    def xfunc(t):
        theta = f(t)
        return a * sqrt(abs(theta)) * cos(theta) * (-1 if theta < 0 else 1)

    def yfunc(t):
        theta = f(t)
Exemple #24
0
    def test_2_ShapesFromNet(self):

        ut_testsrc = os.getenv("TESTSRC")

        ly = pya.Layout()
        ly.read(
            os.path.join(ut_testsrc, "testdata", "algo",
                         "device_extract_l1_with_inv_nodes.gds"))

        l2n = pya.LayoutToNetlist(
            pya.RecursiveShapeIterator(ly, ly.top_cell(), []))

        # only plain backend connectivity

        rmetal1 = l2n.make_polygon_layer(ly.layer(6, 0), "metal1")
        rmetal1_lbl = l2n.make_text_layer(ly.layer(6, 1), "metal1_lbl")
        rvia1 = l2n.make_polygon_layer(ly.layer(7, 0), "via1")
        rmetal2 = l2n.make_polygon_layer(ly.layer(8, 0), "metal2")
        rmetal2_lbl = l2n.make_text_layer(ly.layer(8, 1), "metal2_lbl")

        # Intra-layer
        l2n.connect(rmetal1)
        l2n.connect(rvia1)
        l2n.connect(rmetal2)

        # Inter-layer
        l2n.connect(rmetal1, rvia1)
        l2n.connect(rvia1, rmetal2)
        l2n.connect(rmetal1, rmetal1_lbl)  #  attaches labels
        l2n.connect(rmetal2, rmetal2_lbl)  #  attaches labels

        # Perform netlist extraction
        l2n.extract_netlist()

        self.assertEqual(
            str(l2n.netlist()), """circuit TRANS ($1=$1,$2=$2);
end;
circuit INV2 (OUT=OUT,$2=$3,$3=$4);
  subcircuit TRANS $1 ($1=$4,$2=OUT);
  subcircuit TRANS $2 ($1=$3,$2=OUT);
  subcircuit TRANS $3 ($1=$2,$2=$4);
  subcircuit TRANS $4 ($1=$2,$2=$3);
end;
circuit RINGO ();
  subcircuit INV2 $1 (OUT='FB,OSC',$2=VSS,$3=VDD);
  subcircuit INV2 $2 (OUT=$I20,$2=VSS,$3=VDD);
  subcircuit INV2 $3 (OUT=$I19,$2=VSS,$3=VDD);
  subcircuit INV2 $4 (OUT=$I21,$2=VSS,$3=VDD);
  subcircuit INV2 $5 (OUT=$I22,$2=VSS,$3=VDD);
  subcircuit INV2 $6 (OUT=$I23,$2=VSS,$3=VDD);
  subcircuit INV2 $7 (OUT=$I24,$2=VSS,$3=VDD);
  subcircuit INV2 $8 (OUT=$I25,$2=VSS,$3=VDD);
  subcircuit INV2 $9 (OUT=$I26,$2=VSS,$3=VDD);
  subcircuit INV2 $10 (OUT=$I27,$2=VSS,$3=VDD);
end;
""")

        self.assertEqual(str(l2n.probe_net(rmetal2, pya.DPoint(0.0, 1.8))),
                         "RINGO:FB,OSC")
        sc_path = []
        self.assertEqual(
            str(l2n.probe_net(rmetal2, pya.DPoint(0.0, 1.8), sc_path)),
            "RINGO:FB,OSC")
        self.assertEqual(len(sc_path), 0)
        self.assertEqual(repr(l2n.probe_net(rmetal2, pya.DPoint(-2.0, 1.8))),
                         "None")

        n = l2n.probe_net(rmetal1, pya.Point(2600, 1000), None)
        self.assertEqual(str(n), "INV2:$2")
        sc_path = []
        n = l2n.probe_net(rmetal1, pya.Point(2600, 1000), sc_path)
        self.assertEqual(str(n), "INV2:$2")
        self.assertEqual(len(sc_path), 1)
        a = []
        t = pya.DCplxTrans()
        for sc in sc_path:
            a.append(sc.expanded_name())
            t = t * sc.trans
        self.assertEqual(",".join(a), "$2")
        self.assertEqual(str(t), "r0 *1 2.64,0")

        self.assertEqual(
            str(l2n.shapes_of_net(n, rmetal1, True)),
            "(-980,-420;-980,2420;-620,2420;-620,-420);(-800,820;-800,1180;580,1180;580,820);(-980,2420;-980,3180;-620,3180;-620,2420);(-980,-380;-980,380;-620,380;-620,-380)"
        )

        shapes = pya.Shapes()
        l2n.shapes_of_net(n, rmetal1, True, shapes)
        r = pya.Region()
        for s in shapes.each():
            r.insert(s.polygon)
        self.assertEqual(
            str(r),
            "(-980,-420;-980,2420;-620,2420;-620,-420);(-800,820;-800,1180;580,1180;580,820);(-980,2420;-980,3180;-620,3180;-620,2420);(-980,-380;-980,380;-620,380;-620,-380)"
        )
Exemple #25
0
 def DCplxTrans(self):
     return pya.DCplxTrans(1, self.angle, False, self.centerx, self.centery)
Exemple #26
0
    def produce_impl(self):
        #Calculate layout database unit
        #dbu = self.layout.dbu
        dbu = 1
        size = []
        if len(self.size) < 2:
            if self.debug:
                print("Size < 2 dimension")
            if len(self.size) == 0:
                if self.debug:
                    print(
                        "paramter size has been adjusted to default - invalid data have provided"
                    )
                size = [100.0, 100.0]
            else:
                if self.debug:
                    print("Size has been adjusted to {}:{}".format(
                        self.size[0] / dbu, self.size[0] / dbu))
                size.append(float(self.size[0]) / dbu)
                size.append(float(self.size[0]) / dbu)
        else:
            size.append(float(self.size[0]) / dbu)
            size.append(float(self.size[1]) / dbu)

        ovSize = []
        if len(self.ovsize) < 2:
            if self.debug:
                print("overal size < 2 dimension")
            if len(self.ovsize) == 0:
                if self.debug:
                    print(
                        "paramter size has been adjusted to default - invalid data have provided"
                    )
                ovSize = [100.0, 100.0]
            else:
                ovSize.append(float(self.ovsize[0]) / dbu)
                ovSize.append(float(self.ovsize[0]) / dbu)
        else:
            ovSize.append(float(self.ovsize[0]) / dbu)
            ovSize.append(float(self.ovsize[1]) / dbu)

        armLenght = self.armLenght / dbu
        armWidth = self.armWidth / dbu
        activeArea = [size[0] - self.actOffset, size[1] - self.actOffset]
        woW = self.woW / dbu
        woOP = self.woOP / dbu

        # Membrane Geometry:

        ## arm location on a rectangle = edgeArmOffset
        edgeArmOffset = armWidth / 2 * math.sqrt(2)

        if self.debug:
            print("Size 0:{:.3f}, {}, {}".format(size[0], armLenght, armWidth))
        ## arm starts at following points
        pointArmA = pya.DPoint(size[0] / 2 - edgeArmOffset, size[1] / 2)
        pointArmD = pya.DPoint(size[0] / 2, size[1] / 2 - edgeArmOffset)

        ## arm ends in the point P - might be usefull as a connector point
        pointP = pya.DPoint(size[0] / 2 + armLenght / math.sqrt(2),
                            size[1] / 2 + armLenght / math.sqrt(2))

        ## arm edge points offsets from the center point P
        armEndPointoffset = armWidth / 2 / math.sqrt(2)

        ## Arm edge points in relation to the P point

        pointArmB = pya.DPoint(pointP.x - armEndPointoffset,
                               pointP.y + armEndPointoffset)
        pointArmC = pya.DPoint(pointP.x + armEndPointoffset,
                               pointP.y - armEndPointoffset)

        ## Lets Try to assemble the membrane as 1/4

        polyPoints = []
        polyPoints.append(pya.DPoint(0.0, 0.0))
        polyPoints.append(pya.DPoint(0.0, size[1] / 2))
        polyPoints.append(pointArmA)
        polyPoints.append(pointArmB)
        polyPoints.append(pointArmC)
        polyPoints.append(pointArmD)
        polyPoints.append(pya.DPoint(size[0] / 2, 0.0))

        #Lets put it there
        shapeSet = []

        Poly = pya.DPolygon(polyPoints)
        shapeSet.append(Poly)

        t = pya.DCplxTrans(1.0, 180, False, 0.0, 0.0)
        Poly1 = pya.DPolygon(polyPoints)
        Poly1.transform(t)
        shapeSet.append(Poly1)

        t = pya.DCplxTrans(1.0, 0, True, 0.0, 0.0)
        Poly2 = pya.DPolygon(polyPoints)
        Poly2.transform(t)
        shapeSet.append(Poly2)

        t = pya.DCplxTrans(1.0, 180, True, 0.0, 0.0)
        Poly3 = pya.DPolygon(polyPoints)
        Poly3.transform(t)
        shapeSet.append(Poly3)

        tr = pya.DCplxTrans(1000.0)
        region = pya.Region(shapeSet)
        region.merge()
        region.transform(tr)

        self.cell.shapes(self.l_layer).insert(region)

        #Active Area
        if self.showAct:
            actBox = pya.DBox(-activeArea[0] / 2, -activeArea[1] / 2,
                              activeArea[0] / 2, activeArea[1] / 2)
            self.cell.shapes(self.la_layer).insert(actBox)

        # Etch area - a rectangele limited by the membrane shape and P point
        etchBox = pya.DBox(-pointP.x, -pointP.y, pointP.x, pointP.y)
        etchRegion = pya.Region(etchBox)
        etchRegion.transform(tr)
        tempRegion = region ^ etchRegion
        etchRegion = tempRegion & etchRegion
        self.cell.shapes(self.ool_layer).insert(etchRegion)

        # Heater wire
        if self.genHeater:
            if self.heatType == 0:
                #Hilbert is defined only for square areas. We would fit whatever is smaller

                if activeArea[0] != activeArea[1]:
                    if (activeArea[0] > activeArea[1]):
                        wireArea = activeArea[1] / 2
                    else:
                        wireArea = activeArea[0] / 2
                else:
                    wireArea = activeArea[0] / 2

                #issue num2:
                #  the diagonal contact placemnet is required
                #  so we have to calculate space for the return path
                #  segment separation 1sqg => seg = wireArea / 2^n + 1

                Hcnt = 2**self.heatOrder + 1
                Hseg = wireArea / (Hcnt)
                print("Hseq: {:.3f}".format(Hseg))
                wireAreaRed = wireArea - Hseg
                a = wireAreaRed + wireAreaRed * 1j
                b = wireAreaRed - wireAreaRed * 1j
                z = 0

                for i in range(1, self.heatOrder + 1):
                    w = 1j * z.conjugate()
                    z = numpy.array([w - a, z - b, z + a, b - w]) / 2
                z = z.flatten()
                X = [x.real for x in z]
                Y = [x.imag for x in z]

                heatPoints = []

                for i in range(0, len(X)):
                    heatPoints.append(pya.DPoint(X[i], Y[i]))

                #lets add the return path
                #  start with calculation of intersection to the beam

                #  linEqa = -1*(pointP.y / pointP.x) - valid only for Square
                #
                #print("Linear equation is y = {:.3f}.x".format(linEqa))

                heatInitial = heatPoints[0]

                pointS1 = pya.DPoint(-size[0] / 2, size[1] / 2)
                #pointS2 = pya.DPoint(activeArea[0]/2, -activeArea[1]/2)
                if self.debug:
                    print("P:{:.3f},{:.3f} ; S:{:.3f},{:.3f}".format(
                        -pointP.x, pointP.y, pointS1.x, pointS1.y))
                linEqa = (pointP.y - pointS1.y) / (-pointP.x - pointS1.x)
                linEqb = pointP.y - linEqa * -pointP.x
                if self.debug:
                    print("Line equation is: y={:.3f}x+{:.3f}".format(
                        linEqa, linEqb))

                heatPoints.insert(
                    0, pya.DPoint(heatPoints[0].x - 2 * Hseg, heatPoints[0].y))
                heatPoints.insert(
                    0,
                    pya.DPoint(heatPoints[0].x,
                               linEqa * (heatPoints[0].x + Hseg) + linEqb))
                heatPoints.append(pya.DPoint(heatPoints[len(heatPoints)-1].x, \
                    linEqa*(heatPoints[len(heatPoints)-1].x+Hseg)-linEqb))

                heatPoints.append(pya.DPoint(pointP.x - Hseg,
                                             -pointP.y))  #arm contacts
                heatPoints.insert(0, pya.DPoint(-pointP.x - Hseg, pointP.y))

                #probably somewhere here is a good time to calculate perforations
                # teoretically first opening should be -Heg/2 to the left of the very first
                # point and should repeat in X and Y axis with interval of Hseg
                #

                # center is HeatPoints[2] -Hseg/2 ?
                if self.perfAct:
                    perfW = self.perfSize / 2 / dbu
                    #perfCenter = pya.DPoint(heatPoints[2].x - Hseg, heatPoints[2].y - Hseg)
                    #perfBox = pya.DBox(perfCenter.x-perfW, perfCenter.y-perfW, perfCenter.x+perfW, perfCenter.y-perfW)
                    elCell = self.layout.create_cell("Perforator")
                    perfBox = pya.DPolygon(
                        pya.DBox(-perfW, -perfW, perfW, perfW))
                    if self.roundPath:
                        perfBox = perfBox.round_corners(Hseg / 2, Hseg / 2, 32)
                    elCell.shapes(self.perfl_layer).insert(perfBox)

                    #lets make an array of them
                    x_vect = pya.DVector(2 * Hseg, 0.0)
                    y_vect = pya.DVector(0.0, 2 * Hseg)
                    t = pya.DCplxTrans(heatInitial.x, heatInitial.y + Hseg)
                    perfArr = pya.DCellInstArray(elCell.cell_index(), t,
                                                 x_vect, y_vect, Hcnt - 1,
                                                 Hcnt - 2)

                    self.cell.insert(perfArr)

                    #move to the right coordinates
                    pathT = pya.DCplxTrans(Hseg, 0)
                    heatPath = pya.DPath(heatPoints, self.heatW)
                    heatPathT = heatPath.transformed(pathT)
                    if self.roundPath:
                        heatPathT = heatPath.round_corners(Hseg / 2, 32, 0.001)
                        heatCenter = heatPathT.bbox().center()
                        print(heatCenter)
                        print("Rounded Path center: {}:{}".format(
                            heatCenter.x, heatCenter.y))
                        pathTr = pya.DCplxTrans(-heatCenter.x, -heatCenter.y)
                        heatPathT = heatPathT.transformed(pathTr)
                    self.cell.shapes(self.heatl_layer).insert(heatPathT)
            else:
                print("Wire definition has not been found!")
                #TODO ... other types of heaters

        if self.genWO:
            #we would make a wire connection from the P point to the edge of the membrane
            # overpass on both sides as an option

            # it has to be realized as a set of the 4 path
            print("Overal size: {}:{}".format(ovSize[0], ovSize[1]))
            woPathA = pya.DPath(
                [pointP, pya.DPoint(ovSize[0] / 2, ovSize[1] / 2)], woW, woOP,
                woOP)
            woPathB = pya.DPath([pya.DPoint(-pointP.x, pointP.y), pya.DPoint(-ovSize[0]/2, ovSize[1]/2)],\
                woW, woOP, woOP)
            woPathC = pya.DPath([pya.DPoint(-pointP.x, -pointP.y), pya.DPoint(-ovSize[0]/2, -ovSize[1]/2)],\
                woW, woOP, woOP)
            woPathD = pya.DPath([pya.DPoint(pointP.x, -pointP.y), pya.DPoint(ovSize[0]/2, -ovSize[1]/2)],\
                woW, woOP, woOP)
            self.cell.shapes(self.cntl_layer).insert(woPathA)
            self.cell.shapes(self.cntl_layer).insert(woPathB)
            self.cell.shapes(self.cntl_layer).insert(woPathC)
            self.cell.shapes(self.cntl_layer).insert(woPathD)

        if self.genCnt:
            # Ok that would be fun ...
            #   so at first we should be able to find how many of the IGC we would be able to fit
            #   in between of the perforations (maybe we should count also for the minimal separation)
            #   principally:
            #       single IGS pair consists of 2 wires and 2 gaps = IGSpairW?
            #       testing condition is therefore IGSCnt = floor((Hseg - perfW) / IGSpairW)
            cntW = self.cntW / dbu
            cntSp = self.cntSp / dbu
            cntB = self.cntB / dbu
            cntBunchW = 2 * (cntW + cntSp)
            cntCnt = math.floor((2 * Hseg - 2 * perfW) / cntBunchW)
            if self.debug:
                print("IDC W={}".format(cntBunchW))
                print("IDCs per bunch: {}".format(cntCnt))
            if cntCnt == 0:
                print(
                    "Error: Interdigital contacts with given specs could not be realized because of geometric containts!"
                )
            else:
                #lets make a subcell with interdigital pair
                #   so first calculate the active area - contact bars to get the lenght
                #   contacts singles
                cntCell = self.layout.create_cell("IDC_subcell")
                cntArrCell = self.layout.create_cell("IDC_cell")

                #cntLenght = activeArea - 2*cntB - cntSp

                cntPath_p1 = pya.DPoint((cntSp + cntW) / 2,
                                        activeArea[1] / 2 - cntB)
                cntPath_p2 = pya.DPoint((cntSp + cntW) / 2,
                                        -activeArea[1] / 2 + cntSp +
                                        cntB)  #TODO tohle je asi blbe ...
                cntPath_pA = [cntPath_p1, cntPath_p2]
                cntPath_pB = [cntPath_p1 * -1, cntPath_p2 * -1]

                cntPath_A = pya.DPath(cntPath_pA, cntW, 0.0, 0.0)
                cntPath_B = pya.DPath(cntPath_pB, cntW, 0.0, 0.0)

                cntCell.shapes(self.idcl_layer).insert(cntPath_A)
                cntCell.shapes(self.idcl_layer).insert(cntPath_B)

                #now lets make bunches of cntCnt and center them
                # TODO: tady jsem skoncil ... potreba projit odstavec pod
                #BEGIN
                x_vect = pya.DVector(cntBunchW, 0.0)
                y_vect = pya.DVector(0.0, 0.0)
                if self.debug:
                    print("IDC bunch Vectors: {}, {}, {}, {}".format(\
                        x_vect.x, x_vect.y, y_vect.x, y_vect.y))
                t = pya.DCplxTrans(0, 0)
                cntArr = pya.DCellInstArray(cntCell.cell_index(), t, x_vect,
                                            y_vect, cntCnt, 1)

                #center the origins on top of each other
                #   here we have a bunch of IDCs
                cntArr_center = cntArr.bbox(self.layout).center()
                if self.debug:
                    print("Bunch center: {},{}".format(cntArr_center.x,
                                                       cntArr_center.y))
                t = pya.DCplxTrans(1.0, 0, False, -cntArr_center.x,
                                   -cntArr_center.y)
                cntArr.transform(t)
                cntArrCell.insert(cntArr)

                #   move the array to the position of Hilb. initial and paste it into the overal array

                a_vect = pya.DVector(2 * Hseg, 0.0)
                b_vect = pya.DVector(0.0, 0.0)

                cntLoct = pya.DCplxTrans(1.0, 0, False, heatInitial.x - Hseg,
                                         0.0)

                cntArrAll = pya.DCellInstArray(cntArrCell.cell_index(),
                                               cntLoct, a_vect, b_vect, Hcnt,
                                               1)
                self.cell.insert(cntArrAll)

                #Top and bottom contact
                #  by principle the bar-contact should be horizontally oriented across the active zone
                #  then they should continue to the respective P-points (upright, lowerleft)

                #  Contact bar would be a box from the edge to the edge of active area with a width of
                #  cntB

                # pointCNT1A = pya.DPoint(activeArea[0]/2, activeArea[1]/2)

                # if self.debug:
                #     print("P:{:.3f},{:.3f} ; CNT:{:.3f},{:.3f}".format(-pointP.x, pointP.y, pointCNT1A.x, pointCNT1A.y))
                # linCntEqa = (pointP.y-pointCNT1A.y)/(-pointP.x-pointCNT1A.x)
                # linCntEqb = pointP.y - linCntEqa*-pointP.x

                # if self.debug:
                #     print("CNT line equation is: y={:.3f}x+{:.3f}".format(linEqa,linEqb))

                # pointCNT1B =

                # Contact Bars
                cntBarW = self.cntB / dbu
                cntWoW = self.cntWO / dbu
                shapeSetCNT = []
                #cntBarA
                shapeSetCNT.append(pya.DBox(-activeArea[0]/2, activeArea[1]/2-cntBarW,\
                    activeArea[0]/2, activeArea[1]/2))
                #cntBarB
                shapeSetCNT.append(pya.DBox(-activeArea[0]/2, -activeArea[1]/2,\
                    activeArea[0]/2, -activeArea[1]/2+cntBarW))

                pointS2 = pya.DPoint(activeArea[0] / 2, activeArea[1] / 2)
                #cntWOPathA
                shapeSetCNT.append(
                    pya.DPath([pointS2, pointP], cntWoW, cntWoW / 2,
                              cntWoW).polygon())
                #cntWOPathB
                shapeSetCNT.append(
                    pya.DPath([-pointS2, -pointP], cntWoW, cntWoW / 2,
                              cntWoW).polygon())

                for shape in shapeSetCNT:
                    self.cell.shapes(self.idcl_layer).insert(shape)

                #Vias
                #TODO: repair position of the vias

                cntViaW = cntWoW * 0.9 / 2  # 10% smaller then the wire
                tr = pya.DCplxTrans(1.0, 45.0, False, pya.DVector(pointP))
                cntViaA = pya.DPolygon(pya.DBox(-cntViaW, -cntViaW,\
                    cntViaW, cntViaW)).transform(tr)
                tr = pya.DCplxTrans(1.0, 45.0, False, pya.DVector(-pointP))
                cntViaB = pya.DPolygon(pya.DBox(-cntViaW, -cntViaW,\
                    cntViaW, cntViaW)).transformed(tr)
                self.cell.shapes(self.lvia_layer).insert(cntViaA)
                self.cell.shapes(self.lvia_layer).insert(cntViaB)
 def tr_to(obj,itr=False):
     trs=[pya.DCplxTrans(1,-deltaangle,False,pc.x,pc.y)]
     if itr:trs=[pya.ICplxTrans.from_dtrans(tr) for tr in trs]
     for tr in trs:
         obj=obj.transformed(tr)
     return obj
Exemple #28
0
    def produce_impl(self):
        size = []
        if len(self.size) < 2:
            if self.debug:
                print("Size < 2 dimension")
            if len(self.size) == 0:
                if self.debug:
                    print(
                        "paramter size has been adjusted to default - invalid data have provided"
                    )
                size = [100.0, 100.0]
            else:
                if self.debug:
                    print("Size has been adjusted to {}:{}".format(
                        self.size[0] / dbu, self.size[0] / dbu))
                size.append(float(self.size[0]))
                size.append(float(self.size[0]))
        else:
            size.append(float(self.size[0]))
            size.append(float(self.size[1]))

        ovSize = []
        if len(self.ovsize) < 2:
            if self.debug:
                print("overal size < 2 dimension")
            if len(self.ovsize) == 0:
                if self.debug:
                    print(
                        "paramter size has been adjusted to default - invalid data have provided"
                    )
                ovSize = [100.0, 100.0]
            else:
                ovSize.append(float(self.ovsize[0]))
                ovSize.append(float(self.ovsize[0]))
        else:
            ovSize.append(float(self.ovsize[0]))
            ovSize.append(float(self.ovsize[1]))

        #armLenght = self.armLenght
        armWidth = self.armWidth
        armBSS = self.armBMS
        activeArea = [size[0] - self.actOffset, size[1] - self.actOffset]
        #woW = self.woW/dbu
        #woOP = self.woOP/dbu

        # Membrane Geometry:
        memParts = []
        #   Firstly generate the centerpart
        memCenter = pya.Polygon(
            pya.DPolygon(
                pya.DBox(-size[0] / 2, -size[1] / 2, size[0] / 2,
                         size[1] / 2)))
        memParts.append(memParts)
        #   Time for beams
        #   Calculate the BeamArmcenter to the membrane edge, alias beam to memrane spacing
        memBMS = [(ovSize[0]-size[0]/2) -armBSS -armWidth/2,\
            (ovSize[1]-size[1]/2) -armBSS -armWidth/2]

        memBeam1 = pya.Polygon(pya.DPath([\
            pya.DPoint((size[0]-armWidth)/2, size[1]/2),\
            pya.DPoint((size[0]-armWidth)/2, size[1]/2+memBMS[1]),\
            pya.DPoint(-ovSize[0]/2, size[1]/2+memBMS[1])], armWidth).polygon())
        memParts.append(memBeam1)

        memBeam2 = pya.Polygon(pya.DPath([\
            pya.DPoint(-size[0]/2, (size[1]/2)-armWidth/2),\
            pya.DPoint(-size[0]-memBMS[0], size[1]/2-armWidth/2),\
            pya.DPoint(-size[0]-memBMS[0], -ovSize[1]/2)], armWidth).polygon())
        memParts.append(memBeam2)

        memBeam3 = pya.Polygon(pya.DPath([\
            pya.DPoint((-size[0]+armWidth)/2, -size[1]/2),\
            pya.DPoint((-size[0]+armWidth)/2, -size[1]/2-memBMS[1]),\
            pya.DPoint(ovSize[0]/2, -size[1]/2-memBMS[1])], armWidth).polygon())
        memParts.append(memBeam3)

        memBeam4 = pya.Polygon(pya.DPath([\
            pya.DPoint(size[0]/2, (-size[1]-armWidth)/2),\
            pya.DPoint(size[0]+memBMS[0], -size[1]/2+armWidth/2),\
            pya.DPoint(size[0]+memBMS[0], ovSize[1]/2)], armWidth).polygon())
        memParts.append(memBeam4)

        #here it would be probably useful to put them all into one polygon object (hopefully it\
        # would work ;))
        if self.debug:
            print(memParts)
            for member in memParts:
                self.cell.shapes(self.l_layer).insert(member)
        tr = pya.DCplxTrans(1000.0)  #workaround for difference in DBU
        region = pya.Region(memParts)
        region.merge()
        region.transform(tr)
        self.cell.shapes(self.l_layer).insert(region)

        #Active Area
        actBox = pya.DBox(-activeArea[0]/2, -activeArea[1]/2,\
             activeArea[0]/2, activeArea[1]/2)
        if self.showAct:
            self.cell.shapes(self.la_layer).insert(actBox)

        # Etch area - in this variant the overal size of membrane
        etchRegion = pya.Region(actBox)
        etchRegion.transform(tr)

        tempRegion = region ^ etchRegion
        etchRegion = tempRegion & etchRegion
        self.cell.shapes(self.ool_layer).insert(etchRegion)