Ejemplo n.º 1
0
def find_corners(source, dest):
    """Find the corners given two points
    Points given as cartesian co-ordinates tuple (x,y)
    Returns a list of tuples of corners
    If in straight line, then return emtpy list
    """

    # if incompatible material, return empty list
    if (source[2] != dest[2] and dr.get_contact([source[2], dest[2]]) is None):
        return False

    # straight line => no corners
    if source[0] == dest[0] or source[1] == dest[1]:
        if source[2] == dest[2]:
            return []  # same material, no corner
        else:
            # different material, "corner" can be anywhere along axis
            dir = 0 if source[0] != dest[0] else 1
            points = []
            for i in range(source[dir], dest[dir],
                           -1 if dest[dir] < source[dir] else 1):
                points.append((i, source[1],
                               dest[2]) if not dir else (source[0], i,
                                                         dest[2]))
            return points

    return [(source[0], dest[1], dest[2]), (dest[0], source[1], dest[2])]
Ejemplo n.º 2
0
def l_pattern(s, d):
    """Returns list of routes if source and dest can be connected with a
    L-shaped pattern. If on adjacent layers, then allow layer change anywhere
    along the route.
    """

    # filter out incident and i
    if is_incident(s, d) or is_i(s, d):
        return []

    # get corners
    c1_x, c1_y = s[0], d[1]
    c2_x, c2_y = d[0], s[1]

    # same material => just connect
    if s[2] == d[2]:
        w = dr.material_width[s[2]]  # get material width
        c1 = (c1_x, c1_y, s[2], w)
        c2 = (c2_x, c2_y, s[2], w)
        return [[add_width(s, w), ci, add_width(d, w)] for ci in [c1, c2]]

    # get contact
    contact = dr.get_contact([s[2], d[2]])
    if contact:
        w1 = dr.material_width[s[2]]
        p1 = add_width(s, w1)
        w2 = dr.material_width[d[2]]
        p2 = add_width(d, w2)
        routes = []
        for c in [(c1_x, c1_y), (c2_x, c2_y)]:
            corner = sandwich_contact(c[0], c[1], s[2], d[2], contact)
            routes.append([p1] + corner + [p2])
        return routes
    else:
        return []
Ejemplo n.º 3
0
 def mat_cost(p):
     """Returns cost of material cost in a given pair p
     """
     p1, p2 = p[0], p[1]
     mat1, mat2 = p1[2], p2[2]
     estimate = ((dr.material_cost[mat1] + dr.material_cost[mat2]) / 2)
     contact = dr.get_contact([mat1, mat2])
     if mat1 != mat2 and contact is not None:
         estimate += dr.material_cost[contact] * dr.material_width[contact]
     return estimate
Ejemplo n.º 4
0
def pattern_2(s, d, first_wps):
    """Given source, destination, and list of first waypoints,
    Returns routes with first waypoint and one corner to the destination
    """
    s_layer, d_layer = dr.get_mat_layer(s[2]), dr.get_mat_layer(d[2])

    # require more than two layer transitions
    if abs(s_layer - d_layer) > 4:
        return []

    # determine possible materials of first waypoint
    wp1_mat = []
    for i in range(s_layer // 2 - 1, s_layer // 2 + 2):
        if i < 0: continue
        if abs(i - d_layer // 2) <= 1:
            wp1_mat.append(dr.mat_layers[2 * i])
    # remove poly if not routing with poly
    no_poly = not any([m in ['poly', 'pc'] for m in [s[2], d[2]]])
    if no_poly and 'poly' in wp1_mat:
        wp1_mat.remove('poly')

    routes = []
    for wp1 in first_wps:
        p0 = add_width(s, dr.material_width[s[2]])
        for mat in wp1_mat:
            w = dr.material_width[mat]
            p1 = (wp1[0], wp1[1], mat, w)  # first waypoint

            # generate contact for first waypoint if needed
            if mat != s[2]:
                contact = dr.get_contact([s[2], mat])
                sandwich = sandwich_contact(wp1[0], wp1[1], s[2], mat, contact)
                first_part = [p0] + sandwich
                first_part = first_part[:-1]
            else:
                first_part = [p0]

            # generate second waypoint
            for pattern in l_pattern(p1, d):
                route = first_part + pattern

                # check if any three points are co-linear
                has_colinear = False
                for i in range(len(route) - 3):
                    if is_colinear(route[i], route[i + 1], route[i + 2]):
                        has_colinear = True
                        break

                # add route
                if not has_colinear:
                    routes.append(first_part + pattern)

    return routes
Ejemplo n.º 5
0
def incident(s, d):
    """Returns route if source and dest can be connected with just layer change
    or if already connect. Returns [] otherwise
    """

    if s == d:
        width = dr.material_width[s[2]]
        return [[add_width(s, width), add_width(d, width)]]
    elif (s[0], s[1]) == (d[0], d[1]):  # same position, different material
        contact = dr.get_contact([s[2], d[2]])
        width = dr.material_width[contact]
        if contact:  # valid contact
            return [[
                add_width(s, width), (s[0], s[1], contact, width),
                add_width(d, width)
            ]]
        else:  # no contact between materials
            return []
    else:
        return []
Ejemplo n.º 6
0
def i_pattern(s, d):
    """Returns list of routes if source and dest can be connected with a
    straight line. If on adjacent layers, then allow layer change anywhere
    along the way. Return empty list if no route is valid.
    """

    # filter out incident
    if is_incident(s, d): return []

    # check if same x or same y
    if not is_i(s, d):
        return []

    # same material => simply connect
    if s[2] == d[2]:
        w = dr.material_width[s[2]]
        return [[add_width(s, w), add_width(d, w)]]

    # get contact
    contact = dr.get_contact([s[2], d[2]])
    if contact:  # has valid contact => place contact anywhere on route
        routes = []
        drt = aux.get_dir(s, d)  # direction: 0 horizontal, 1 vertical
        w = dr.material_width[contact]

        # get points along route
        for i in range(abs(s[drt] - d[drt]) + 1):
            if drt:  # vertical
                x, y = s[0], min(s[1], d[1]) + i
            else:  # horizontal
                x, y = min(s[0], d[0]) + i, s[1]
            # add route
            routes.append([add_width(s, w)] +
                          sandwich_contact(x, y, s[2], d[2], contact) +
                          [add_width(d, w)])
        return routes
    else:
        return []