Example #1
0
def bitmarker(nx, ny, d=1, layer=3):
    nA = 4
    if (nx >= 32) or (ny >= 32):
        nA = 5
    marker = A_marker(number_of_squares=nA, d=d, layer=layer)
    if nx > 0:
        markerBx = B_marker_bits(nx, d=d, layer=layer)
        marker = gp.fast_boolean(marker, markerBx, "or", layer=layer)
    if ny > 0:
        markerBy = B_marker_bits(ny, d=d, layer=layer).mirror((d, -d))
        marker = gp.fast_boolean(marker, markerBy, "or", layer=layer)
    return marker
Example #2
0
def m_wire(w, L, l=0.5, d=0.5, up=False, layer=1):
    p1 = [(-L / 2, 0), (L / 2, 0)]
    if up == False:
        p2 = [(0, 0), (-l * math.cos(math.pi / 3), -l * math.sin(math.pi / 3))]
    else:
        p2 = [(0, 0), (l * math.cos(math.pi / 3), l * math.sin(math.pi / 3))]
    arm1 = gp.PolyPath(p1, w, layer=layer)
    arm2 = gp.PolyPath(p2, w, layer=layer)
    arm3 = gp.PolyPath(p2, w, layer=layer).translate(-d, 0)
    arm4 = gp.PolyPath(p2, w, layer=layer).translate(d, 0)
    t = gp.fast_boolean(arm1, arm2, "or", layer=layer)
    n = gp.fast_boolean(arm3, arm4, "or", layer=layer)
    m = gp.fast_boolean(t, n, "or", layer=layer)
    return m
Example #3
0
def build_mask(cell, wgt, final_layer=None, final_datatype=None):
    """ Builds the appropriate mask according to the resist specifications and fabrication type.  Does this by applying a boolean 'XOR' or 'AND' operation on the waveguide and clad masks.

        Args:
           * **cell** (gdspy.Cell):  Cell with components.  Final mask is placed in this cell.
           * **wgt** (WaveguideTemplate):  Waveguide template containing the resist information, and layers/datatypes for the waveguides and cladding.

        Keyword Args:
           * **final_layer** (int): layer to place the mask on (defaults to `wgt.clad_layer + 1`)
           * **final_datatype** (int): datatype to place the mask on (defaults to `0`)

        Returns:
           None

    """
    fl = wgt.clad_layer + 1 if final_layer == None else final_layer
    fd = 0 if final_datatype == None else final_datatype

    polygons = cell.get_polygons(by_spec=True)
    try:
        pWG = polygons[(wgt.wg_layer, wgt.wg_datatype)]
        pCLAD = polygons[(wgt.clad_layer, wgt.clad_datatype)]
    except KeyError:
        print(
            "Warning! No objects written to layer/datatype specified by WaveguideTemplate"
        )
    if wgt.resist == "+":
        cell.add(
            gdspy.fast_boolean(
                pWG,
                pCLAD,
                "xor",
                precision=0.001,
                max_points=199,
                layer=fl,
                datatype=fd,
            ))
    elif wgt.resist == "-":
        cell.add(
            gdspy.fast_boolean(
                pWG,
                pCLAD,
                "and",
                precision=0.001,
                max_points=199,
                layer=fl,
                datatype=fd,
            ))
Example #4
0
def add_reservoir_to_shape(shape,
                           x_width=2,
                           y_height=0.5,
                           position=(0, 0),
                           layer=1,
                           rotation=0):
    """
    Takes a shape and adds a rectangle of specified width and height to some position
    :param shape: gp.PolygonSet
    :param x_width: in um
    :param y_height: in um
    :param position: (x, y) center of the rectangle
    :param layer: shapes are on layer 1 by default
    :param rotation: float in degrees
    :return: None
    """

    reservoir = gp.Rectangle((-x_width / 2, -y_height / 2),
                             (x_width / 2, y_height / 2),
                             layer=layer).rotate(rotation * math.pi / 180)

    return gp.fast_boolean(shape,
                           reservoir.translate(position[0], position[1]),
                           'or',
                           layer=layer)
Example #5
0
	def build2(self,shape,cell):
		return cell.add(shape)
		for i in range(0,len(input_shape)):
			shape = gdspy.Polygon(input_shape[i],input_layer)
			output_bool = gdspy.fast_boolean(bool_shape,shape, mode, 
				precision=1e-9, max_points=1000, layer=output_layer)
		return shape, output_bool
Example #6
0
    def _find_overlap(cls, geos1, geos2, layer=0):
        """Return a geometry on layer 0 that represents any overlap
		in geometries.
		"""
        geos1 = cls._union_of_geometries(geos1, layer)
        geos2 = cls._union_of_geometries(geos2, layer)
        return gdspy.fast_boolean(geos1, geos2, 'and', layer=layer)
def tessellate(cell, i=199, lyr=None):
    """
    within a cell, an old layer is subtracted from the chip size, and is written to the new layer

    Args:
        cell - gdspy cell
        lyr - layer name

    Return:
        cell with inverted new layer and removed old layer
    """

    mask = []
    if lyr is None:
        layers = cell.get_polygons(by_spec=True)
        for l in layers:
            i = 199
            while hole(cell, l):
                tessellate(cell, i, l)
                i = i - 1
        return None

    polygons = cell.get_polygons(by_spec=True)[lyr]
    box_coord = cell.get_bounding_box()
    bbox = gdspy.Rectangle(box_coord[0], box_coord[1])

    for p in polygons:
        mask.append(gdspy.Polygon(p))

    cell.remove_polygons(lambda pts, layer, datatype: layer == lyr[0])
    result = gdspy.fast_boolean(bbox, mask, 'and', max_points=i, layer=lyr[0])
    # print(len(result.polygons))
    cell.add(result)
Example #8
0
def xor_polygons_phidl(A, B, hash_geom=True):
    """ Given two devices A and B, performs a layer-by-layer XOR diff between
    A and B, and returns polygons representing the differences between A and B.
    """
    from phidl import Device
    import gdspy
    # first do a geometry hash to vastly speed up if they are equal
    if hash_geom and (A.hash_geometry() == B.hash_geometry()):
        return Device()

    D = Device()
    A_polys = A.get_polygons(by_spec=True)
    B_polys = B.get_polygons(by_spec=True)
    A_layers = A_polys.keys()
    B_layers = B_polys.keys()
    all_layers = set()
    all_layers.update(A_layers)
    all_layers.update(B_layers)
    for layer in all_layers:
        if (layer in A_layers) and (layer in B_layers):
            p = gdspy.fast_boolean(A_polys[layer],
                                   B_polys[layer],
                                   operation='xor',
                                   precision=0.001,
                                   max_points=4000,
                                   layer=layer[0],
                                   datatype=layer[1])
        elif (layer in A_layers):
            p = A_polys[layer]
        elif (layer in B_layers):
            p = B_polys[layer]
        if p is not None:
            D.add_polygon(p, layer=layer)
    return D
Example #9
0
def add_double_SmartWall(struct_list,
                         l=5.5,
                         delta_x=0,
                         delta_y=-0.6,
                         relative_y=-0.8,
                         x_superposition=0.15,
                         min_thickness=0.4,
                         layer=2,
                         zigzag=False,
                         zigzag_d=0.3,
                         zigzag_angle=30):
    if -relative_y < min_thickness + 0.3:
        min_thickness = max(0.2, -relative_y - 0.3)
    p1 = [(0, 0), (0, -min_thickness), (-2, -1.5), (-l, -1.5), (-l, 0), (0, 0)]
    p2 = [(-x_superposition, 0), (l, 0), (l, -2), (-0.5, -2), (-0.5, -1.6),
          (-x_superposition, 0)]
    if zigzag == True:
        p1 = straight_to_zigzag_line(p1, zigzag_d, zigzag_angle)
        p2 = straight_to_zigzag_line(p2, zigzag_d, zigzag_angle)
    SW1 = gp.Polygon(p1, layer=layer)
    SW1.translate(delta_x, delta_y)
    SW2 = gp.Polygon(p2, layer=layer)
    SW2.translate(delta_x, delta_y + relative_y)
    SW = gp.fast_boolean(SW1, SW2, "or", layer=layer)
    struct_list.append(SW)
    return struct_list
Example #10
0
def braggGrating(period=.310,
                 NG=400,
                 waveguideWidth=0.5,
                 dwidth=0.05,
                 layerNumber=1):
    # Intialize cells
    name = 'braggCell=' + str(int(period * 1e3)) + '_NG=' + str(
        int(NG)) + '_dwidth=' + str(int(dwidth * 1e3))
    braggCell = gdspy.Cell(name)

    # Calculate Parameters
    L = NG * period

    # Generate main waveguide
    waveguide = gdspy.Rectangle([-L / 2, waveguideWidth / 2 - dwidth / 2],
                                [L / 2, -waveguideWidth / 2 + dwidth / 2],
                                layer=layerNumber)

    # Add side strips
    strips = []
    startRect = -L / 2
    stopRect = -L / 2 + period / 2
    for k in range(0, NG):
        strips.append(
            gdspy.Rectangle([startRect, waveguideWidth / 2 + dwidth / 2],
                            [stopRect, -waveguideWidth / 2 - dwidth / 2],
                            layer=layerNumber))

        startRect = startRect + period
        stopRect = stopRect + period

    finalShape = gdspy.fast_boolean(waveguide, strips, 'or', layer=layerNumber)
    braggCell.add(finalShape)
    return braggCell
Example #11
0
    def _union_of_geometries(cls, geometries, layer):
        """Returns union of all geometries in list ``geometries``"""
        result = geometries[0]
        for geo in geometries[1:]:
            result = gdspy.fast_boolean(result, geo, 'or', layer=layer)

        return result
    def _etch_target_helper(self):

        etch_layers = []
        etch_targets = []
        layer_target = []

        for elay in self.layerstack.etch_layers:
            etch_layers.append(
                self.gds.get_polygons(by_spec=True,
                                      depth=None)[(elay.layer, elay.datatype)])
            layer_target.append((elay.layer, elay.datatype))
        for etar in self.layerstack.etch_targets:
            etch_targets.append(
                self.gds.get_polygons(by_spec=True,
                                      depth=None)[(etar.layer, etar.datatype)])

        # Do this with gdspy! dont go back to Device.

        etch_layers, etch_targets
        new_polygons = []
        for i in range(len(etch_targets)):
            p = gdspy.fast_boolean(operand1=etch_targets[i],
                                   operand2=etch_layers[i],
                                   operation='not',
                                   precision=1e-9,
                                   max_points=4000,
                                   layer=702,
                                   datatype=727)
            new_polygons.append(p)
        self._remove_etch_layers()

        for i in range(len(new_polygons)):
            self.gds.add_polygon(new_polygons[i], layer=layer_target[i])
Example #13
0
def A_marker(number_of_squares=4, d=1, layer=3):
    square = gp.Rectangle((0, 0), (d, -d), layer=layer)
    marker = gp.Rectangle((0, 0), (d, -d), layer=layer)
    for _ in range(1, number_of_squares):
        square.translate(d, -d)
        marker = gp.fast_boolean(marker, square, "or", layer=layer)
    return marker
Example #14
0
    def generate_ground(self):
        x = self.g_w
        y = self.g_h
        z = self.center
        t = self.g_t
        ground1 = gdspy.Rectangle((z[0] - x / 2, z[1] - y / 2),
                                  (z[0] + x / 2, z[1] + y / 2))
        ground2 = gdspy.Rectangle((z[0] - x / 2 + t, z[1] - y / 2 + t),
                                  (z[0] + x / 2 - t, z[1] + y / 2 - t))
        ground = gdspy.fast_boolean(ground1, ground2, 'not')
        for key in self.remove_ground:
            factor = 1
            if key == 'left':
                if self.remove_ground[key] != None:
                    factor = self.remove_ground[key]
                ground = gdspy.fast_boolean(
                    ground,
                    gdspy.Rectangle(
                        (z[0] - x / 2, z[1] - factor * y / 2 + t),
                        (z[0] - x / 2 + t, z[1] + factor * y / 2 - t)), 'not')
            if key == 'right':
                if self.remove_ground[key] != None:
                    factor = self.remove_ground[key]
                ground = gdspy.fast_boolean(
                    ground,
                    gdspy.Rectangle(
                        (z[0] + x / 2, z[1] - factor * y / 2 + t),
                        (z[0] + x / 2 - t, z[1] + factor * y / 2 - t)), 'not')
            if key == 'top':
                if self.remove_ground[key] != None:
                    factor = self.remove_ground[key]
                ground = gdspy.fast_boolean(
                    ground,
                    gdspy.Rectangle(
                        (z[0] - factor * x / 2 + t, z[1] + y / 2),
                        (z[0] + factor * x / 2 - t, z[1] + y / 2 - t)), 'not')
            if key == 'bottom':
                if self.remove_ground[key] != None:
                    factor = self.remove_ground[key]
                ground = gdspy.fast_boolean(
                    ground,
                    gdspy.Rectangle(
                        (z[0] - factor * x / 2 + t, z[1] - y / 2),
                        (z[0] + factor * x / 2 - t, z[1] - y / 2 + t)), 'not')

        return ground
Example #15
0
def star(w, L, layer=1):
    p1 = [(-L * math.cos(math.pi / 3), L * math.sin(math.pi / 3)), (0, 0),
          (-L * math.cos(math.pi / 3), -L * math.sin(math.pi / 3))]
    p2 = [(0, 0), (L, 0)]
    arm1 = gp.PolyPath(p1, w, layer=layer)
    arm2 = gp.PolyPath(p2, w, layer=layer)
    star = gp.fast_boolean(arm1, arm2, "or", layer=layer)
    return star
Example #16
0
def parallel_wire(w, L, distance=1, layer=1, orientation=0):
    """
    Returns a gdspy shape with two parallel wires centered at origin
    """
    w1 = single_wire(w, L, layer=layer,
                     orientation=0).translate(0, distance / 2)
    w2 = single_wire(w, L, layer=layer,
                     orientation=0).translate(0, -distance / 2)
    angle_rad = orientation * math.pi / 180
    return gp.fast_boolean(w1, w2, 'or', layer=layer).rotate(angle_rad)
Example #17
0
def barred_hexagon(w, L, layer=1):
    p1 = [(-L, 0), (-L * math.cos(math.pi / 3), L * math.sin(math.pi / 3)),
          (+L * math.cos(math.pi / 3), L * math.sin(math.pi / 3)), (L, 0),
          (L * math.cos(math.pi / 3), -L * math.sin(math.pi / 3)),
          (-L * math.cos(math.pi / 3), -L * math.sin(math.pi / 3)), (-L, 0)]
    p2 = [(-3 * L, 0), (3 * L, 0)]
    hexagon = gp.PolyPath(p1, w, layer=layer)
    bar = gp.PolyPath(p2, w, layer=layer)
    struct = gp.fast_boolean(hexagon, bar, "or", layer=layer)
    return struct
Example #18
0
def t_wire(w, L, l=1, up=False, layer=1):
    p1 = [(-L / 2, 0), (L / 2, 0)]
    if up == False:
        p2 = [(0, 0), (-l * math.cos(math.pi / 3), -l * math.sin(math.pi / 3))]
    else:
        p2 = [(0, 0), (l * math.cos(math.pi / 3), l * math.sin(math.pi / 3))]
    arm1 = gp.PolyPath(p1, w, layer=layer)
    arm2 = gp.PolyPath(p2, w, layer=layer)
    t = gp.fast_boolean(arm1, arm2, "or", layer=layer)
    return t
Example #19
0
def test_notempty():
    name = 'cr_notempty'
    c = gdspy.Cell(name)
    ref = gdspy.CellReference(name, (1, -1), 90, 2, True)
    ref.translate(-1, 1)
    c.add(gdspy.Rectangle((0, 0), (1, 2), 2, 3))
    assert ref.area() == 8
    assert ref.area(True) == {(2, 3): 8}
    err = numpy.array(((0, 0), (4, 2))) - ref.get_bounding_box()
    assert numpy.max(numpy.abs(err)) < 1e-15
    assert ref.origin[0] == ref.origin[1] == 0
    r = gdspy.fast_boolean(ref.get_polygons(), gdspy.Rectangle((0, 0), (4, 2)),
                           'xor', 1e-6, 0)
    assert r is None
    d = ref.get_polygons(True)
    assert len(d.keys()) == 1
    r = gdspy.fast_boolean(d[(2, 3)], gdspy.Rectangle((0, 0), (4, 2)), 'xor',
                           1e-6, 0)
    assert r is None
Example #20
0
def test_notempty():
    name = 'cr_notempty'
    c = gdspy.Cell(name)
    ref = gdspy.CellReference(name, (1, -1), 90, 2, True)
    ref.translate(-1, 1)
    c.add(gdspy.Rectangle((0, 0), (1, 2), 2, 3))
    assert ref.area() == 8
    assert ref.area(True) == {(2, 3): 8}
    err = numpy.array(((0, 0), (4, 2))) - ref.get_bounding_box()
    assert numpy.max(numpy.abs(err)) < 1e-15
    assert ref.origin[0] == ref.origin[1] == 0
    r = gdspy.fast_boolean(ref.get_polygons(), gdspy.Rectangle((0, 0), (4, 2)),
                           'xor', 1e-6, 0)
    assert r is None
    d = ref.get_polygons(True)
    assert len(d.keys()) == 1
    r = gdspy.fast_boolean(d[(2, 3)], gdspy.Rectangle((0, 0), (4, 2)), 'xor',
                           1e-6, 0)
    assert r is None
Example #21
0
	def boolean(self,input_shape,bool_shape, input_layer=0, output_layer=0,mode='or'):

		if(mode != 'or' or mode != 'not' or mode != 'and'):
			raise Exception('mode should be either 'not', 'or', or 'and'')

		for i in range(0,len(input_shape)):
			shape = gdspy.Polygon(input_shape[i],input_layer)
			output_bool = gdspy.fast_boolean(bool_shape,shape, mode, 
				precision=1e-9, max_points=1000, layer=output_layer)
		return shape, output_bool
Example #22
0
	def boolean(self,input_shape,bool_shape, input_layer=0, output_layer=0,mode='or'):

		# if(mode != str('or') or mode != str('not') or mode != str('and')):
		# 	raise Exception('mode should be either \'not\', \'or\', or \'and\'')

		for i in range(0,len(input_shape)):
			shape = gdspy.Polygon(input_shape[i],input_layer)
			bool_shape = gdspy.fast_boolean(bool_shape,shape,mode, 
				precision=1e-9, max_points=1000, layer=output_layer)

		return bool_shape
def invert_layer(cell, lyr, keep=False):

    mask = []
    polygons = cell.get_polygons(by_spec=True)[lyr]
    box_coord = cell.get_bounding_box()
    bbox = gdspy.Rectangle(box_coord[0], box_coord[1])

    for p in polygons:
        mask.append(gdspy.Polygon(p))
    cell.remove_polygons(lambda pts, layer, datatype: layer == lyr[0]
                         ) if keep is False else None
    result = gdspy.fast_boolean(bbox, mask, 'not', layer=lyr[0])
    return result
Example #24
0
def hollow_box(size, border_width, layer=0):

    outer = gd.Rectangle((0, 0), size)
    inner = gd.Rectangle((border_width, border_width),
                         (size[0] - border_width, size[1] - border_width))

    hbox = gd.fast_boolean(outer, inner, 'not', layer=layer)
    ends = {
        'A': (0, size[1] / 2),
        'B': (size[0] / 2, 0),
        'C': (size[0] / 2, size[1]),
        'D': (size[0], size[1] / 2),
        'CENTER': (size[0] / 2, size[1] / 2)
    }
    epsz = {'A': size[1], 'CENTER': None}

    return gtools.classes.GDStructure(hbox, ends, epsz)
Example #25
0
def lattice_cutter(lattice, objectlist, mode = 'and', layer = 0):
    #=====================================
    # Cut a lattice up using fast_boolean \\
    #=========================================================================
    # Arguments:    lattice     :   output of lattice() function            ||
    #               objectlist  :   list of objects that intersect lattice  ||
    #    (optional) mode        :   what boolean operation to apply         ||
    #    (optional) layer       :   layer to put resulting structure on     ||
    #=========================================================================
    if type(objectlist) is not type([]):
        objectlist = [objectlist]

    for i in objectlist:
        if i.compound:
            lattice = lattice_cutter(lattice, i.compound)
        lattice.structure = gd.fast_boolean(lattice.structure, i.structure, mode, layer = layer)

    return lattice
Example #26
0
    def __xor__(self, other):
        pts1, pts2 = [], []
        for e in self.elements:
            s1 = e.shape.transform_copy(e.transformation)
            pts1.append(s1.points)
        for e in other.elements:
            s1 = e.shape.transform_copy(e.transformation)
            pts2.append(s1.points)

        if (len(pts1) > 0) and (len(pts2) > 0):
            p1 = gdspy.PolygonSet(polygons=pts1)
            p2 = gdspy.PolygonSet(polygons=pts2)

            ply = gdspy.fast_boolean(p1, p2, operation='not')
            elems = ElementList()
            for points in ply.polygons:
                elems += Polygon(shape=points, layer=self.layer)
            self.elements = elems
        return self
Example #27
0
def shapely_to_gdspy(
        geom_shapely: Union[Polygon, MultiPolygon]) -> gdspy.Polygon:
    if isinstance(geom_shapely, Polygon):
        return shapely_to_gdspy_polygon(geom_shapely)
    elif isinstance(geom_shapely, MultiPolygon):
        polygon_gdspy = shapely_to_gdspy_polygon(geom_shapely[0])
        for polygon_shapely in geom_shapely[1:]:
            polygon_gdspy_append = shapely_to_gdspy_polygon(polygon_shapely)

            polygon_gdspy = dataprep_cleanup_gdspy(
                gdspy.fast_boolean(polygon_gdspy,
                                   polygon_gdspy_append,
                                   'or',
                                   max_points=MAX_POINTS,
                                   precision=GLOBAL_OPERATION_PRECISION),
                do_cleanup=GLOBAL_DO_CLEANUP)

        return polygon_gdspy
    else:
        raise TypeError(
            "input must be a Shapely Polygon or a Shapely MultiPolygon")
Example #28
0
        def compute_intersection(polygon_1, polygon_2):
            '''
            Wrapper function around the gdspy module to take as input
            two polygons and return polygon_1-polygon_2 
            Explicit NOT operation is only performed if the bounding boxes
            of the two polygons do not intersect.
            '''
            if check_bounding_box(polygon_1, polygon_2):
                gds_poly1 = gdspy.Polygon(polygon_1, 0)
                gds_poly2 = gdspy.Polygon(polygon_2, 0)
                gds_poly = gdspy.fast_boolean(gds_poly1,
                                              gds_poly2,
                                              'not',
                                              layer=1)
                if gds_poly is None:
                    return []
                else:
                    return gds_poly.polygons

            else:
                return [polygon_1]
Example #29
0
def shapely_to_gdspy_polygon(polygon_shapely: Polygon) -> gdspy.Polygon:
    if not isinstance(polygon_shapely, Polygon):
        raise ValueError("input must be a Shapely Polygon")
    else:
        ext_coord_list = list(zip(*polygon_shapely.exterior.coords.xy))
        polygon_gdspy = gdspy.Polygon(ext_coord_list)
        if len(polygon_shapely.interiors):
            for interior in polygon_shapely.interiors:
                int_coord_list = list(zip(*interior.coords.xy))
                polygon_gdspy_int = gdspy.Polygon(int_coord_list)

                polygon_gdspy = dataprep_cleanup_gdspy(
                    gdspy.fast_boolean(polygon_gdspy,
                                       polygon_gdspy_int,
                                       'not',
                                       max_points=MAX_POINTS,
                                       precision=GLOBAL_OPERATION_PRECISION),
                    do_cleanup=GLOBAL_DO_CLEANUP)
        else:
            pass
        return polygon_gdspy
Example #30
0
def boxOutline():
    # initialize cell
    outlineCell = gdspy.Cell('outline')

    # define an outer box
    outerBox = gdspy.Rectangle([-outerBoxWidth / 2, -outerBoxWidth / 2],
                               [outerBoxWidth / 2, outerBoxWidth / 2],
                               layer=layerNumber)

    # define an inner box
    innerBox = gdspy.Rectangle([-innerBoxWidth / 2, -innerBoxWidth / 2],
                               [innerBoxWidth / 2, innerBoxWidth / 2],
                               layer=layerNumber)

    # now subtract the two
    outline = gdspy.fast_boolean(outerBox, innerBox, 'xor', layer=layerNumber)

    # update the cell
    outlineCell.add(outline)

    # return the cell
    return outlineCell
Example #31
0
def flatten(objectlist, endpoints, endpoint_dims, layer = 0):
    #===========================
    # FLatten a list of objects \\
    #=========================================================================
    # Flattening will cause all objects in the objectlist to be placed in   ||
    # one single layer and remove boundaries between them if there are any. ||
    # All layer information will become lost! If you just want to combine   ||
    # structures while keeping layer information, use cluster()             ||
    #                                                                       ||
    # Arguments:    objectlist      :   list of objects (GDStructure)       ||
    #               endpoints       :   dictionary of new endpoints         ||
    #               endpoint_dims   :   dictionary of new endpoint sizes    ||
    #=========================================================================
    # Define function to allow for recursive walk through list and pick out all
    # compound structures
    def stacker(inlist):

        outlist = []
        for i in inlist:
            if i.compound:
                outlist += [i] + stacker(i.compound)
            else:
                outlist += [i]

        return outlist

    objectlist = stacker(objectlist)

    ends = copy.deepcopy(endpoints)
    epsz = copy.deepcopy(endpoint_dims)

    objs = []
    for i in objectlist:
        objs.append(i.structure)

    return gtools.classes.GDStructure(gd.fast_boolean(objs, None, 'or', layer = layer), ends, epsz)
Example #32
0
                      number_of_paths=3, distance=0.7, layer=6)
path_cell.add(l1path)


## ------------------------------------------------------------------ ##
##      POLYGON OPERATIONS
## ------------------------------------------------------------------ ##

## Boolean operations can be executed with either gdspy polygons or
## point lists).  The operations are union, intersection, subtraction,
## symmetric subtracion (respectively 'or', 'and', 'not', 'xor').
oper_cell = gdspy.Cell('OPERATIONS')

## Here we subtract the previously created spiral from a rectangle with
## the 'not' operation.
oper_cell.add(gdspy.fast_boolean(gdspy.Rectangle((10,-4), (17,4)), path3,
                                 'not', layer=1))

## Polygon offset (inset and outset) can be used, for instance, to
## define safety margins around shapes.

spec = {'layer': 7}
path4 = gdspy.Path(0.5, (21, -5)).segment(3, '+x', **spec)\
        .turn(4, 'r', **spec).turn(4, 'rr', **spec)\
        .segment(3, **spec)
oper_cell.add(path4)

## Merge all parts into a single polygon.
merged = gdspy.fast_boolean(path4, None, 'or', max_points=0)

## Offset the path shape by 0.5 and add it to the cell.
oper_cell.add(gdspy.offset(merged, 1, layer=8))