예제 #1
0
    def test_get_pin_line(self):
        """
        The get_pin_line returns the correct string for a kicad pin.
        """

        writer = KiCAD()

        pin = Pin('1', (-300, 100), (-600, 100))
        line = writer.get_pin_line(pin)
        self.assertEqual(
            line, 'X ~ 1 -6667 1111 3333 R 60 60 %(unit)d %(convert)d B\n')

        pin = Pin('1', (300, 100), (600, 100))
        line = writer.get_pin_line(pin)
        self.assertEqual(
            line, 'X ~ 1 6667 1111 3333 L 60 60 %(unit)d %(convert)d B\n')

        pin = Pin('2', (0, -1300), (0, -1500))
        line = writer.get_pin_line(pin)
        self.assertEqual(
            line, 'X ~ 2 0 -16667 2222 U 60 60 %(unit)d %(convert)d B\n')

        pin = Pin('2', (0, 1300), (0, 1500))
        line = writer.get_pin_line(pin)
        self.assertEqual(
            line, 'X ~ 2 0 16667 2222 D 60 60 %(unit)d %(convert)d B\n')

        pin = Pin('2', (0, 1300), (0, 1500), Label(0, 0, 'name', 'center', 0))
        line = writer.get_pin_line(pin)
        self.assertEqual(
            line, 'X name 2 0 16667 2222 D 60 60 %(unit)d %(convert)d B\n')
예제 #2
0
 def test_pin_bounds(self):
     '''Test bounds() for individual pins'''
     pin = Pin(0, Point(2, 5), Point(4, 3))
     top_left, bottom_right = pin.bounds()
     self.assertEqual(top_left.x, 2)
     self.assertEqual(top_left.y, 3)
     self.assertEqual(bottom_right.x, 4)
     self.assertEqual(bottom_right.y, 5)
 def test_pin_bounds(self):
     '''Test bounds() for individual pins'''
     pin = Pin(0, Point(2, 5), Point(4, 3))
     top_left, bottom_right = pin.bounds()
     self.assertEqual(top_left.x, 2)
     self.assertEqual(top_left.y, 3)
     self.assertEqual(bottom_right.x, 4)
     self.assertEqual(bottom_right.y, 5)
예제 #4
0
 def parse_pin(self, pin):
     """ Extract a pin of a body. """
     pin_number = pin.get('pin_number')
     p1 = self.parse_point(pin.get('p1'))
     p2 = self.parse_point(pin.get('p2'))
     parsed_pin = Pin(pin_number, p1, p2)
     if pin.get('label') is not None:
         parsed_pin.label = self.parse_label(pin.get('label'))
     parsed_pin.styles = pin.get('styles') or {}
     return parsed_pin
 def parse_pin(self, pin):
     """ Extract a pin of a body. """
     pin_number = pin.get("pin_number")
     p1 = self.parse_point(pin.get("p1"))
     p2 = self.parse_point(pin.get("p2"))
     parsed_pin = Pin(pin_number, p1, p2)
     if pin.get("label") is not None:
         parsed_pin.label = self.parse_label(pin.get("label"))
     parsed_pin.styles = pin.get("styles") or {}
     return parsed_pin
예제 #6
0
 def parse_pin(self, pin):
     """ Extract a pin of a body. """
     pin_number = pin.get('pin_number')
     p1 = self.parse_point(pin.get('p1'))
     p2 = self.parse_point(pin.get('p2'))
     parsed_pin = Pin(pin_number, p1, p2)
     if pin.get('label') is not None:
         parsed_pin.label = self.parse_label(pin.get('label'))
     parsed_pin.styles = pin.get('styles') or {}
     return parsed_pin
예제 #7
0
 def test_pin_label_bounds(self):
     '''Test bounds() for a pin with a label'''
     lab = Label(0, 0, 'foo', align='left', rotation=0)
     mkbounds(lab, 1, 3, 2, 6)
     pin = Pin(0, Point(2, 2), Point(4, 3), lab)
     top_left, bottom_right = pin.bounds()
     self.assertEqual(top_left.x, 1)
     self.assertEqual(top_left.y, 2)
     self.assertEqual(bottom_right.x, 4)
     self.assertEqual(bottom_right.y, 6)
 def test_pin_label_bounds(self):
     '''Test bounds() for a pin with a label'''
     lab = Label(0, 0, 'foo', align='left', rotation=0)
     mkbounds(lab, 1, 3, 2, 6)
     pin = Pin(0, Point(2, 2), Point(4, 3), lab)
     top_left, bottom_right = pin.bounds()
     self.assertEqual(top_left.x, 1)
     self.assertEqual(top_left.y, 2)
     self.assertEqual(bottom_right.x, 4)
     self.assertEqual(bottom_right.y, 6)
예제 #9
0
 def parse_pin(self, args):
     """ Returns a parsed pin. """
     # Pin declaration, seems to only be done once per pin
     pid, x1, y1, x0, y0, _rot, _side, _inv = [int(a) for a in args.split()]
     # _rot and _side are not needed, because the x-y data tells us what we
     # need to know. _inv is used to draw the little inverted signal cirles.
     thispin = Pin(pid, (x0, y0), (x1, y1))
     subdata = self.sub_nodes(['L'])
     if len(subdata['label']) > 0:
         # I suppose if there's more than one label, just go with the first
         thispin.label = subdata['label'][0]
     return ('pin', thispin)
예제 #10
0
 def parse_pin(self, args):
     """ Returns a parsed pin. """
     # Pin declaration, seems to only be done once per pin
     pid, x1, y1, x0, y0, _rot, _side, _inv = [int(a) for a in args.split()]
     # _rot and _side are not needed, because the x-y data tells us what we
     # need to know. _inv is used to draw the little inverted signal cirles.
     thispin = Pin(pid, (x0, y0), (x1, y1))
     subdata = self.sub_nodes(['L'])
     if len(subdata['label']) > 0:
         # I suppose if there's more than one label, just go with the first
         thispin.label = subdata['label'][0]
     return ('pin', thispin)
예제 #11
0
 def parse_pin(self, args):
     """ Returns a parsed pin. """
     # Pin declaration, seems to only be done once per pin
     pid, xe, ye, xb, yb, rot, side, inv = [int(a) for a in args.split()]
     thispin = Pin(pid, (xb, yb), (xe, ye))
     subdata = defaultdict(list)
     for phrase in self.stream:
         cmd, _sep, args = phrase.partition(' ')
         if cmd not in ('L'):
             self.stream.push(phrase)
             break
         k, v = self.parsenode(cmd)(args)
         subdata[k].append(v)
     if len(subdata['label']) > 0:
         # I suppose if there's more than one label, just go with the first
         thispin.label = subdata['label'][0]
     return ('pin', thispin)
예제 #12
0
 def parse_pin(self, args):
     """ Returns a parsed pin. """
     # Pin declaration, seems to only be done once per pin
     pid, xe, ye, xb, yb, rot, side, inv = [int(a) for a in args.split()]
     thispin = Pin(pid, (xb, yb), (xe, ye))
     subdata = defaultdict(list)
     for phrase in self.stream:
         cmd, _sep, args = phrase.partition(' ')
         if cmd not in ('L'):
             self.stream.push(phrase)
             break
         k, v = self.parsenode(cmd)(args)
         subdata[k].append(v)
     if len(subdata['label']) > 0:
         # I suppose if there's more than one label, just go with the first
         thispin.label = subdata['label'][0]
     return ('pin', thispin)
예제 #13
0
    def test_get_pin_line(self):
        """
        The get_pin_line returns the correct string for a kicad pin.
        """

        writer = KiCAD()

        pin = Pin('1', (-300, 100), (-600, 100))
        line = writer.get_pin_line(pin)
        self.assertEqual(
            line, 'X ~ 1 ' 
            + str(int(-600 / MULT)) + ' ' 
            + str(int(100 / MULT)) + ' ' 
            + str(int(300 / MULT)) + ' ' 
            + 'R 60 60 %(unit)d %(convert)d B\n')

        pin = Pin('1', (300, 100), (600, 100))
        line = writer.get_pin_line(pin)
        self.assertEqual(
            line, 'X ~ 1 '
            + str(int(600 / MULT)) + ' '
            + str(int(100 / MULT)) + ' '
            + str(int(300 / MULT)) + ' '
            + 'L 60 60 %(unit)d %(convert)d B\n')

        pin = Pin('2', (0, -1300), (0, -1500))
        line = writer.get_pin_line(pin)
        self.assertEqual(
            line, 'X ~ 2 0 '
            + str(int(-1500 / MULT)) + ' '
            + str(int(200 / MULT)) + ' U 60 60 %(unit)d %(convert)d B\n')

        pin = Pin('2', (0, 1300), (0, 1500))
        line = writer.get_pin_line(pin)
        self.assertEqual(
            line, 'X ~ 2 0 '
            + str(int(1500 / MULT)) + ' '
            + str(int(200 / MULT)) + ' D 60 60 %(unit)d %(convert)d B\n')

        pin = Pin('2', (0, 1300), (0, 1500),
                  Label(0, 0, 'name', align='center', rotation=0))
        line = writer.get_pin_line(pin)
        self.assertEqual(
            line, 'X name 2 0 '
            + str(int(1500 / MULT)) + ' '
            + str(int(200 / MULT)) + ' D 60 60 %(unit)d %(convert)d B\n')
예제 #14
0
 def test_create_new_pin(self):
     """ Test the creation of a new empty pin. """
     p1 = Point(0, 1)
     p2 = Point(2, 3)
     pin = Pin(0, p1, p2, 'abc')
     assert pin.label == 'abc'
     assert pin.p1.x == p1.x
     assert pin.p1.y == p1.y
     assert pin.p2.x == p2.x
     assert pin.p2.y == p2.y
     assert pin.pin_number == 0
def get_pin(shape):
    """ Return a Pin for the given shape, or None """

    if shape.type == 'rectangle':
        x = shape.x + shape.width / 2
        y = shape.y + shape.height / 2
    elif shape.type == 'circle':
        x, y = shape.x, shape.y
    else:
        return None

    return Pin('', (x, y), (x, y))
예제 #16
0
    def test_bounds_pins_shapes(self):
        '''Test SBody.bounds() when some extremes are from pins, others shapes'''
        point = Point(0, 0)
        pin1 = Pin('foo', point, point)
        pin2 = Pin('bar', point, point)
        sh1 = Shape()
        sh2 = Shape()
        mkbounds(pin1, 3, 2, 3, 3)
        mkbounds(pin2, 3, 3, 5, 3)
        mkbounds(sh1, 3, 3, 3, 4)
        mkbounds(sh2, 1, 3, 3, 3)
        self.bod.add_pin(pin1)
        self.bod.add_pin(pin2)
        self.bod.add_shape(sh1)
        self.bod.add_shape(sh2)

        top_left, bottom_right = self.bod.bounds()
        self.assertEqual(top_left.x, 1)
        self.assertEqual(top_left.y, 2)
        self.assertEqual(bottom_right.x, 5)
        self.assertEqual(bottom_right.y, 4)
예제 #17
0
    def test_bounds_pins(self):
        '''Test bounds() with just pins included'''
        pins = [Pin(str(i), Point(0, 0), Point(0, 0)) for i in range(4)]
        # checking body.bounds(), not the pins, so override their bounds()
        # methods
        for i, pin in enumerate(pins):
            bounds = [3, 3, 3, 3]
            bounds[i] = 2 * i
            mkbounds(pin, bounds[0], bounds[1], bounds[2], bounds[3])
            self.bod.add_pin(pin)

        top_left, bottom_right = self.bod.bounds()
        self.assertEqual(top_left.x, 0)
        self.assertEqual(top_left.y, 2)
        self.assertEqual(bottom_right.x, 4)
        self.assertEqual(bottom_right.y, 6)
예제 #18
0
    def make_body_from_symbol(self, lib, symbol_name):
        """ Construct an openjson Body from an eagle symbol in a library. """

        body = Body()

        symbol = [
            s for s in get_subattr(lib, 'symbols.symbol')
            if s.name == symbol_name
        ][0]

        for wire in symbol.wire:
            body.add_shape(
                Line((self.make_length(wire.x1), self.make_length(wire.y1)),
                     (self.make_length(wire.x2), self.make_length(wire.y2))))

        for rect in symbol.rectangle:
            x = self.make_length(rect.x1)
            y = self.make_length(rect.y1)
            width = self.make_length(rect.x2) - x
            height = self.make_length(rect.y2) - y
            body.add_shape(Rectangle(x, y + height, width, height))

        pin_map = {}

        for pin in symbol.pin:
            connect_point = (self.make_length(pin.x), self.make_length(pin.y))
            null_point = self.get_pin_null_point(connect_point, pin.length,
                                                 pin.rot)
            label = self.get_pin_label(pin, null_point)
            pin_map[pin.name] = Pin(pin.name, null_point, connect_point, label)
            body.add_pin(pin_map[pin.name])

        ann_map = {}

        for text in symbol.text:
            x = self.make_length(text.x)
            y = self.make_length(text.y)
            content = '' if text.valueOf_ is None else text.valueOf_
            rotation = self.make_angle('0' if text.rot is None else text.rot)
            if content == '>NAME':
                ann_map['name'] = Annotation(content, x, y, rotation, 'true')
            elif content == '>VALUE':
                ann_map['value'] = Annotation(content, x, y, rotation, 'true')
            else:
                body.add_shape(Label(x, y, content, 'left', rotation))

        return body, pin_map, ann_map
예제 #19
0
    def parse_x_line(self, parts):
        """ Parse an X (Pin) line """
        name, num, direction = parts[1], parts[2], parts[6]
        p2x, p2y, pinlen = int(parts[3]), int(parts[4]), int(parts[5])

        if direction == 'U':  # up
            p1x = p2x
            p1y = p2y + pinlen
            label_x = p2x - 20
            label_y = p2y + int(pinlen / 2)
            label_rotation = 1.5
        elif direction == 'D':  # down
            p1x = p2x
            p1y = p2y - pinlen
            label_x = p2x - 20
            label_y = p2y - int(pinlen / 2)
            label_rotation = 1.5
        elif direction == 'L':  # left
            p1x = p2x - pinlen
            p1y = p2y
            label_x = p2x - int(pinlen / 2)
            label_y = p2y + 20
            label_rotation = 0
        elif direction == 'R':  # right
            p1x = p2x + pinlen
            p1y = p2y
            label_x = p2x + int(pinlen / 2)
            label_y = p2y + 20
            label_rotation = 0
        else:
            raise ValueError('unexpected pin direction', direction)

        if name == '~':
            label = None
        else:
            label = Label(label_x,
                          label_y,
                          name,
                          align='center',
                          rotation=label_rotation)

        return Pin(num, (p1x, p1y), (p2x, p2y), label)
예제 #20
0
    def _convert_library(self, struct):
        for image in struct.library.image:
            component = Component(image.image_id)
            self.design.add_component(image.image_id, component)
            sym = Symbol()
            body = Body()
            component.add_symbol(sym)
            sym.add_body(body)
            for pin in image.pin:
                body.add_pin(
                    Pin(pin.pin_id, self.to_pixels(pin.vertex),
                        self.to_pixels(pin.vertex)))
                for padstack in struct.library.padstack:
                    if padstack.padstack_id == pin.padstack_id:
                        shapes = [shape.shape for shape in padstack.shape]
                        for shape in self._convert_shapes(
                                shapes, self.to_pixels(pin.vertex)):
                            body.add_shape(shape)
                        break

            for outline in image.outline:
                for shape in self._convert_shapes([outline.shape]):
                    body.add_shape(shape)
예제 #21
0
    def make_body_from_symbol(self, lib, symbol_name, pin_number_lookup):
        """ Construct an openjson SBody from an eagle symbol in a library. """

        body = SBody()

        symbol = [
            s for s in get_subattr(lib, 'symbols.symbol')
            if s.name == symbol_name
        ][0]

        for wire in symbol.wire:
            body.add_shape(self.make_shape_for_wire(wire))

        for rect in symbol.rectangle:
            rotation = make_angle('0' if rect.rot is None else rect.rot)
            x1, y1 = rotate_point(
                (self.make_length(rect.x1), self.make_length(rect.y1)),
                rotation)
            x2, y2 = rotate_point(
                (self.make_length(rect.x2), self.make_length(rect.y2)),
                rotation)
            ux, uy = min(x1, x2), max(y1, y2)
            lx, ly = max(x1, x2), min(y1, y2)
            body.add_shape(Rectangle(ux, uy, lx - ux, uy - ly))

        for poly in symbol.polygon:
            map(body.add_shape, self.make_shapes_for_poly(poly))

        for circ in symbol.circle:
            body.add_shape(self.make_shape_for_circle(circ))

        pin_map = {}

        for pin in symbol.pin:
            connect_point = (self.make_length(pin.x), self.make_length(pin.y))
            null_point = self.get_pin_null_point(connect_point, pin.length,
                                                 pin.rot)
            label = self.get_pin_label(pin, null_point)
            pin_map[pin.name] = Pin(pin_number_lookup(pin.name), null_point,
                                    connect_point, label)
            if pin.direction:
                pin_map[pin.name].add_attribute('eaglexml_direction',
                                                pin.direction)
            if pin.visible:
                pin_map[pin.name].add_attribute('eaglexml_visible',
                                                pin.visible)
            body.add_pin(pin_map[pin.name])

        ann_map = {}

        for text in symbol.text:
            x = self.make_length(text.x)
            y = self.make_length(text.y)
            content = '' if text.valueOf_ is None else text.valueOf_
            rotation = make_angle('0' if text.rot is None else text.rot)
            align = 'right' if is_mirrored(text.rot) else 'left'
            if rotation == 0.5:
                rotation = 1.5
            if content.lower() == '>name':
                ann_map['name'] = Annotation(content, x, y, rotation, 'true')
            elif content.lower() == '>value':
                ann_map['value'] = Annotation(content, x, y, rotation, 'true')
            else:
                body.add_shape(
                    Label(x, y, content, align=align, rotation=rotation))

        return body, pin_map, ann_map