コード例 #1
0
    def test_polygon_with_hole(self):

        r = Region()
        r.insert(Box(0, 0, 1000, 1000))
        r -= Region(Box(250, 250, 700, 700))

        fragments = frag.Fragments(r[0], 300)
        self.assertEqual(
            repr(fragments),
            "(0,0;0,350),(0,350;0,650),(0,650;0,1000),(0,1000;350,1000),(350,1000;650,1000),(650,1000;1000,1000),(1000,1000;1000,650),(1000,650;1000,350),(1000,350;1000,0),(1000,0;650,0),(650,0;350,0),(350,0;0,0);(250,250;700,250),(700,250;700,700),(700,700;250,700),(250,700;250,250)"
        )

        poly = fragments.to_polygon()
        self.assertEqual(str(poly), str(r[0]))

        # apply alternating shifts
        s = 10
        for ff in fragments.fragments():
            for f in ff:
                f.move(s)
                s = -s

        poly = fragments.to_polygon()
        self.assertEqual(
            str(poly),
            "(350,-10;350,10;-10,10;-10,350;10,350;10,650;-10,650;-10,990;350,990;350,1010;650,1010;650,990;1010,990;1010,650;990,650;990,350;1010,350;1010,10;650,10;650,-10/240,260;710,260;710,690;240,690)"
        )
コード例 #2
0
ファイル: Shapes.py プロジェクト: Pradeep505/KLayout-python
 def init_regions(self):
     origin = DPoint(0, 0)
     hor_box = DBox(origin - DPoint(self.l / 2, self.t / 2),
                    DPoint(self.l / 2, self.t / 2))
     vert_box = DBox(origin - DPoint(self.t / 2, self.l / 2),
                     DPoint(self.t / 2, self.l / 2))
     cross = (Region(hor_box) + Region(vert_box)).merge()
     if self.inverse:
         self.empty_region.insert(cross)
     else:
         self.metal_region.insert(cross)
コード例 #3
0
    def __init__(self, origin, trans_in=None, inverse=False):
        ## MUST BE IMPLEMENTED ##
        self.connections = []  # DPoint list with possible connection points
        self.connection_edges = [
        ]  # indexes of edges that are intended to connect to other polygons
        # indexes in "self.connection_edges" where Sonnet ports
        # should be placed
        self.sonnet_port_connections = []
        self.angle_connections = []  #list with angle of connecting elements
        ## MUST BE IMLPEMENTED END ##

        self.connection_ptrs = [
        ]  # pointers to connected structures represented by their class instances

        self.origin = origin
        self.inverse = inverse
        self.metal_region = Region()
        self.empty_region = Region()
        self.metal_regions = {}
        self.empty_regions = {}
        self.metal_regions["default"] = self.metal_region
        self.empty_regions["default"] = self.empty_region

        self.metal_region.merged_semantics = True
        self.empty_region.merged_semantics = True
        self.DCplxTrans_init = None
        self.ICplxTrans_init = None

        if (trans_in is not None):
            # if( isinstance( trans_in, ICplxTrans ) ): <==== FORBIDDEN
            if (isinstance(trans_in, DCplxTrans)):
                self.DCplxTrans_init = trans_in
                self.ICplxTrans_init = ICplxTrans().from_dtrans(trans_in)
            elif (isinstance(trans_in, CplxTrans)):
                self.DCplxTrans_init = DCplxTrans().from_itrans(trans_in)
                self.ICplxTrans_init = ICplxTrans().from_trans(trans_in)
            elif (isinstance(trans_in, DTrans)):
                self.DCplxTrans_init = DCplxTrans(trans_in, 1)
                self.ICplxTrans_init = ICplxTrans(
                    Trans().from_dtrans(trans_in), 1)
            elif (isinstance(trans_in, Trans)):
                self.DCplxTrans_init = DCplxTrans(
                    DTrans().from_itrans(trans_in), 1)
                self.ICplxTrans_init = ICplxTrans(trans_in, 1)

        self._init_regions_trans()
コード例 #4
0
    def __init__(self, cell_name):
        # getting main references of the application
        app = klayout.db.Application.instance()
        mw = app.main_window()
        self.lv = mw.current_view()
        self.cv = None
        self.cell = None
        self.region_ph = Region()
        self.region_el = Region()

        #this insures that lv and cv are valid objects
        if (self.lv == None):
            self.cv = mw.create_layout(1)
            self.lv = mw.current_view()
        else:
            self.cv = self.lv.active_cellview()

        # find or create the desired by programmer cell and layer
        layout = self.cv.layout()
        layout.dbu = 0.001
        if (layout.has_cell(cell_name)):
            self.cell = layout.cell(cell_name)
        else:
            self.cell = layout.create_cell(cell_name)

        info = klayout.db.LayerInfo(1, 0)
        info2 = klayout.db.LayerInfo(2, 0)
        self.layer_ph = layout.layer(info)  # photoresist layer
        self.layer_el = layout.layer(info2)  # e-beam lithography layer

        # clear this cell and layer
        self.cell.clear()

        # setting layout view
        self.lv.select_cell(self.cell.cell_index(), 0)
        self.lv.add_missing_layers()

        # design parameters that were passed to the last
        # self.draw(...) call are stored here as ordered dict
        self.design_pars = OrderedDict()
コード例 #5
0
    def test_lshaped_polygon(self):

        r = Region()
        r.insert(Box(0, 0, 1000, 500))
        r.insert(Box(0, 0, 500, 1000))
        r.merge()

        fragments = frag.Fragments(r[0], 300)
        self.assertEqual(
            repr(fragments),
            "(0,0;0,350),(0,350;0,650),(0,650;0,1000),(0,1000;500,1000),(500,1000;500,500),(500,500;1000,500),(1000,500;1000,0),(1000,0;650,0),(650,0;350,0),(350,0;0,0)"
        )

        poly = fragments.to_polygon()
        self.assertEqual(str(poly), str(r[0]))

        # apply alternating shifts
        s = 10
        for ff in fragments.fragments():
            for f in ff:
                f.move(s)
                s = -s

        poly = fragments.to_polygon()
        self.assertEqual(
            str(poly),
            "(350,-10;350,10;-10,10;-10,350;10,350;10,650;-10,650;-10,990;510,990;510,490;1010,490;1010,10;650,10;650,-10)"
        )
コード例 #6
0
    def place(self, dest, layer_i=-1, region_name=None):
        if (layer_i != -1):
            r_cell = Region(dest.begin_shapes_rec(layer_i))
            for primitive in self.primitives.values():
                primitive.place(r_cell, region_name=region_name)

            temp_i = dest.layout().layer(
                klayout.db.LayerInfo(PROGRAM.LAYER1_NUM, 0))
            dest.shapes(temp_i).insert(r_cell)
            dest.layout().clear_layer(layer_i)
            dest.layout().move_layer(temp_i, layer_i)
            dest.layout().delete_layer(temp_i)
        else:
            for primitive in self.primitives.values():
                primitive.place(dest, region_name=region_name)
コード例 #7
0
ファイル: Shapes.py プロジェクト: Pradeep505/KLayout-python
 def init_regions(self):
     origin = DPoint(0, 0)
     Rin = self.r - self.t
     Rout = self.r
     dpts_arr_Rout = [
         DPoint(Rout * cos(2 * pi * i / self.n_pts),
                Rout * sin(2 * pi * i / self.n_pts))
         for i in range(0, self.n_pts)
     ]
     dpts_arr_Rin = [
         DPoint(Rin * cos(2 * pi * i / self.n_pts),
                Rin * sin(2 * pi * i / self.n_pts))
         for i in range(0, self.n_pts)
     ]
     outer_circle = Region(SimplePolygon().from_dpoly(
         DSimplePolygon(dpts_arr_Rout)))
     inner_circle = Region(SimplePolygon().from_dpoly(
         DSimplePolygon(dpts_arr_Rin)))
     ring = outer_circle - inner_circle
     #self.metal_region.insert(ring)
     if self.inverse:
         self.empty_region = ring
     else:
         self.metal_region = ring
コード例 #8
0
    def init_regions(self):

        w_pad, g_pad = self._pad_cpw_params["w"], self._pad_cpw_params["g"]
        w_feed, g_feed = self._feedline_cpw_params[
            "w"], self._feedline_cpw_params["g"]
        x, y = self._ground_connector_width + self._back_gap, 0

        metal_points = [
            DPoint(x, y + w_pad / 2),
            DPoint(x + self._pad_length, y + w_pad / 2),
            DPoint(x + self._pad_length + self._transition_length,
                   y + w_feed / 2),
            DPoint(x + self._pad_length + self._transition_length,
                   y - w_feed / 2),
            DPoint(x + self._pad_length, y - w_pad / 2),
            DPoint(x, y - w_pad / 2)
        ]
        metal_poly = DSimplePolygon(metal_points)

        self.metal_region.insert(metal_poly)

        protect_points = [
            DPoint(x - self._back_gap, y + w_pad / 2 + g_pad),
            DPoint(x + self._pad_length, y + w_pad / 2 + g_pad),
            DPoint(x + self._pad_length + self._transition_length,
                   y + w_feed / 2 + g_feed),
            DPoint(x + self._pad_length + self._transition_length,
                   y - w_feed / 2 - g_feed),
            DPoint(x + self._pad_length, y - w_pad / 2 - g_pad),
            DPoint(x - self._back_gap, y - w_pad / 2 - g_pad)
        ]

        protect_poly = DSimplePolygon(protect_points)
        protect_region = Region(protect_poly)

        empty_region = protect_region - self.metal_region

        self.empty_region.insert(empty_region)

        self.connections = [
            DPoint(0, 0),
            DPoint(x + self._pad_length + self._transition_length, 0)
        ]
        self.angle_connections = [pi, 0]
コード例 #9
0
ファイル: Shapes.py プロジェクト: Pradeep505/KLayout-python
    def init_regions(self):
        origin = DPoint(0, 0)
        w = self.out_a / 2 - self.in_a / 2

        rec1 = Rectangle(origin, w, w)
        p2 = origin + DPoint(self.in_a + w, 0)
        rec2 = Rectangle(p2, w, w)
        p3 = origin + DPoint(self.in_a + w, self.in_a + w)
        rec3 = Rectangle(p3, w, w)
        p4 = origin + DPoint(0, self.in_a + w)
        rec4 = Rectangle(p4, w, w)

        tmp_reg = Region()

        rec1.place(tmp_reg)
        rec2.place(tmp_reg)
        rec3.place(tmp_reg)
        rec4.place(tmp_reg)

        rec = Rectangle(origin, self.out_a, self.out_a)
        rec.place(self.metal_region)

        self.empty_region = tmp_reg
        self.connections = [self.center]
コード例 #10
0
    def place(self, dest, layer_i=-1, region_name=None, merge=False):
        r_cell = None
        metal_region = None
        empty_region = None
        if (region_name == None):
            metal_region = self.metal_region
            empty_region = self.empty_region
        else:
            if (region_name in self.metal_regions):
                metal_region = self.metal_regions[region_name]
            else:
                metal_region = Region()

            if (region_name in self.empty_regions):
                empty_region = self.empty_regions[region_name]
            else:
                empty_region = Region()

        if (layer_i != -1):
            r_cell = Region(dest.begin_shapes_rec(layer_i))
            temp_i = dest.layout().layer(
                klayout.db.LayerInfo(PROGRAM.LAYER1_NUM, 0))
            r_cell += metal_region
            r_cell -= empty_region

            if (merge is True):
                r_cell.merge()

            dest.shapes(temp_i).insert(r_cell)
            dest.layout().clear_layer(layer_i)
            dest.layout().move_layer(temp_i, layer_i)
            dest.layout().delete_layer(temp_i)
        if (layer_i == -1
            ):  # dest is interpreted as instance of Region() class
            dest += metal_region
            dest -= empty_region
            if (merge is True):
                dest.merge()
コード例 #11
0
class Element_Base():
    '''
    @brief: base class for simple single-layer or multi-layer elements and objects that are consisting of
            several polygons.
            metal_region polygons will be added to the design
            empty_region polygons will be erased from the background with 
            metal region polygons already added.

    '''
    def __init__(self, origin, trans_in=None, inverse=False):
        ## MUST BE IMPLEMENTED ##
        self.connections = []  # DPoint list with possible connection points
        self.connection_edges = [
        ]  # indexes of edges that are intended to connect to other polygons
        # indexes in "self.connection_edges" where Sonnet ports
        # should be placed
        self.sonnet_port_connections = []
        self.angle_connections = []  #list with angle of connecting elements
        ## MUST BE IMLPEMENTED END ##

        self.connection_ptrs = [
        ]  # pointers to connected structures represented by their class instances

        self.origin = origin
        self.inverse = inverse
        self.metal_region = Region()
        self.empty_region = Region()
        self.metal_regions = {}
        self.empty_regions = {}
        self.metal_regions["default"] = self.metal_region
        self.empty_regions["default"] = self.empty_region

        self.metal_region.merged_semantics = True
        self.empty_region.merged_semantics = True
        self.DCplxTrans_init = None
        self.ICplxTrans_init = None

        if (trans_in is not None):
            # if( isinstance( trans_in, ICplxTrans ) ): <==== FORBIDDEN
            if (isinstance(trans_in, DCplxTrans)):
                self.DCplxTrans_init = trans_in
                self.ICplxTrans_init = ICplxTrans().from_dtrans(trans_in)
            elif (isinstance(trans_in, CplxTrans)):
                self.DCplxTrans_init = DCplxTrans().from_itrans(trans_in)
                self.ICplxTrans_init = ICplxTrans().from_trans(trans_in)
            elif (isinstance(trans_in, DTrans)):
                self.DCplxTrans_init = DCplxTrans(trans_in, 1)
                self.ICplxTrans_init = ICplxTrans(
                    Trans().from_dtrans(trans_in), 1)
            elif (isinstance(trans_in, Trans)):
                self.DCplxTrans_init = DCplxTrans(
                    DTrans().from_itrans(trans_in), 1)
                self.ICplxTrans_init = ICplxTrans(trans_in, 1)

        self._init_regions_trans()

    def init_regions(self):
        raise NotImplementedError

    # first it makes trans_init displacement
    # then the rest of the trans_init
    # then displacement of the current state to the origin
    # after all, origin should be updated
    def _init_regions_trans(self):
        self.init_regions()  # must be implemented in every subclass

        dr_origin = DSimplePolygon([DPoint(0, 0)])
        if (self.DCplxTrans_init is not None):
            # constructor trans displacement
            dCplxTrans_temp = DCplxTrans(1, 0, False,
                                         self.DCplxTrans_init.disp)
            self.make_trans(dCplxTrans_temp)
            dr_origin.transform(dCplxTrans_temp)

            # rest of the constructor trans functions
            dCplxTrans_temp = self.DCplxTrans_init.dup()
            dCplxTrans_temp.disp = DPoint(0, 0)
            self.make_trans(dCplxTrans_temp)
            dr_origin.transform(dCplxTrans_temp)

        # translation to the old origin (self.connections are already contain proper values)
        self.make_trans(DCplxTrans(1, 0, False,
                                   self.origin))  # move to the origin
        self.origin += dr_origin.point(0)

    def make_trans(self, dCplxTrans):
        if (dCplxTrans is not None):
            iCplxTrans = ICplxTrans().from_dtrans(dCplxTrans)
            self.metal_region.transform(iCplxTrans)
            self.empty_region.transform(iCplxTrans)
            self._update_connections(dCplxTrans)
            self._update_alpha(dCplxTrans)

    def _update_connections(self, dCplxTrans):
        if (dCplxTrans is not None):
            # the problem is, if i construct polygon with multiple points
            # their order in poly_temp.each_point() doesn't coinside with the
            # order of the list that was passed to the polygon constructor
            # so, when i perform transformation and try to read new values through poly_temp.each_point()
            # they values are rearranged
            # solution is: i need to create polygon for each point personally, and the initial order presists
            for i, pt in enumerate(self.connections):
                poly_temp = DSimplePolygon([pt])
                poly_temp.transform(dCplxTrans)
                self.connections[i] = poly_temp.point(0)

    def _update_alpha(self, dCplxTrans):
        if (dCplxTrans is not None):
            dCplxTrans_temp = dCplxTrans.dup()
            dCplxTrans_temp.disp = DPoint(0, 0)

            for i, alpha in enumerate(self.angle_connections):
                poly_temp = DSimplePolygon([DPoint(cos(alpha), sin(alpha))])
                poly_temp.transform(dCplxTrans_temp)
                pt = poly_temp.point(0)
                self.angle_connections[i] = atan2(pt.y, pt.x)

    def _update_origin(self, dCplxTrans):
        if (dCplxTrans is not None):
            poly_temp = DSimplePolygon([self.origin])
            poly_temp.transform(dCplxTrans)
            self.origin = poly_temp.point(0)

    def place(self, dest, layer_i=-1, region_name=None, merge=False):
        r_cell = None
        metal_region = None
        empty_region = None
        if (region_name == None):
            metal_region = self.metal_region
            empty_region = self.empty_region
        else:
            if (region_name in self.metal_regions):
                metal_region = self.metal_regions[region_name]
            else:
                metal_region = Region()

            if (region_name in self.empty_regions):
                empty_region = self.empty_regions[region_name]
            else:
                empty_region = Region()

        if (layer_i != -1):
            r_cell = Region(dest.begin_shapes_rec(layer_i))
            temp_i = dest.layout().layer(
                klayout.db.LayerInfo(PROGRAM.LAYER1_NUM, 0))
            r_cell += metal_region
            r_cell -= empty_region

            if (merge is True):
                r_cell.merge()

            dest.shapes(temp_i).insert(r_cell)
            dest.layout().clear_layer(layer_i)
            dest.layout().move_layer(temp_i, layer_i)
            dest.layout().delete_layer(temp_i)
        if (layer_i == -1
            ):  # dest is interpreted as instance of Region() class
            dest += metal_region
            dest -= empty_region
            if (merge is True):
                dest.merge()

    def add_sonnet_port(self, connection_idx):
        '''
        @brief: sets internal marker that during export to Sonnet
                   the port should be placed at the connection edge
                   with an index 'connection_idx' 
        '''
        print(self.connections)
        self.sonnet_port_connections.append(self.connections[connection_idx])
コード例 #12
0
 def __erase_in_layer(self, layer, box):
     reg_l = self._reg_from_layer(layer)
     box_reg = Region(box)
     reg_l &= box_reg