コード例 #1
0
    def parse_fzp(self, fzp_file):
        """ Parse the Fritzing component file """

        tree = ElementTree(file=fzp_file)

        try:
            prefix = tree.find('label').text
        except AttributeError:
            pass
        else:
            self.component.add_attribute('_prefix', prefix)

        symbol = Symbol()
        self.component.add_symbol(symbol)

        self.body = Body()
        symbol.add_body(self.body)

        self.cid2termid.update(self.parse_terminals(tree))
        self.terminals.update(self.cid2termid.values())

        layers = tree.find('views/schematicView/layers')
        if layers is None:
            self.image = None
        else:
            self.image = layers.get('image')
コード例 #2
0
    def make_body_from_symbol(self, lib, symbol_name):
        """ Contruct 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))))

        return body
コード例 #3
0
    def parse_fzp(self, fzp_file):
        """ Parse the Fritzing component file """

        tree = ElementTree(file=fzp_file)

        try:
            prefix = tree.find('label').text
        except AttributeError:
            pass
        else:
            self.component.add_attribute('_prefix', prefix)

        symbol = Symbol()
        self.component.add_symbol(symbol)

        self.body = Body()
        symbol.add_body(self.body)

        self.cid2termid.update(self.parse_terminals(tree))
        self.terminals.update(self.cid2termid.values())

        layers = tree.find('views/schematicView/layers')
        if layers is None:
            self.image = None
        else:
            self.image = layers.get('image')
コード例 #4
0
    def test_bounds_all_elts(self):
        '''bounds() with all the elements competing'''
        net = Net('foo')
        mkbounds(net, 3, 3, -1, -2)
        self.des.add_net(net)

        annot = Annotation('foo', 3, 3, 0, True)
        mkbounds(annot, 3, 3, 3, 5)
        self.des.design_attributes.add_annotation(annot)

        libcomp = Component('bar')
        libcomp.add_symbol(Symbol())
        libcomp.symbols[0].add_body(Body())
        mkbounds(libcomp.symbols[0].bodies[0], 0, 0, 3, 3)
        self.des.add_component('foo', libcomp)

        compinst = ComponentInstance('bar', 'foo', 0)
        compinst.add_symbol_attribute(SymbolAttribute(3, 0, 0, False))
        self.des.add_component_instance(compinst)

        top_left, btm_right = self.des.bounds()
        self.assertEqual(top_left.x, -1)
        self.assertEqual(top_left.y, -2)
        self.assertEqual(btm_right.x, 6)
        self.assertEqual(btm_right.y, 5)
コード例 #5
0
    def make_body_from_symbol(self, lib, symbol_name):
        """ Contruct 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))))

        return body
コード例 #6
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
コード例 #7
0
    def build_symbols(self, has_convert):
        """ Build all Symbols and Bodies for this component. The
        has_convert argument should be True if there are DeMorgan
        convert bodies. """

        for _ in range(2 if has_convert else 1):
            symbol = Symbol()
            for _ in range(self.num_units):
                symbol.add_body(Body())
            self.component.add_symbol(symbol)
コード例 #8
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
コード例 #9
0
    def parse(self):
        """ Parses a component from the library, returns a Compenent. """
        part = Component(self.filename)
        part.add_symbol(Symbol())
        part.symbols[0].add_body(Body())

        tree = ViewDrawBase.parse(self)
        for k, v in tree['attr']:
            part.add_attribute(k, v)
        for shape in tree['shape'] + sum(tree['lines'], []):
            part.symbols[0].bodies[0].add_shape(shape)
        for pin in tree['pin']:
            part.symbols[0].bodies[0].add_pin(pin)

        return part
コード例 #10
0
 def parse_body(self, body):
     """ Extract a body of a symbol. """
     bdy = Body()
     for pin in body.get('pins'):
         parsed_pin = self.parse_pin(pin)
         bdy.add_pin(parsed_pin)
     for shape in body.get('shapes'):
         parsed_shape = self.parse_shape(shape)
         bdy.add_shape(parsed_shape)
     return bdy
コード例 #11
0
    def test_bounds_parts(self):
        '''test bounds() with just components in the design'''
        libcomp = Component('bar')
        libcomp.add_symbol(Symbol())
        libcomp.symbols[0].add_body(Body())
        mkbounds(libcomp.symbols[0].bodies[0], 0, 0, 10, 10)
        self.des.add_component('foo', libcomp)
        for (x, y) in ((1, 3), (3, 2), (5, 3), (3, 7)):
            compinst = ComponentInstance(str((x, y)), 'foo', 0)
            compinst.add_symbol_attribute(SymbolAttribute(x, y, 0, False))
            self.des.add_component_instance(compinst)

        top_left, btm_right = self.des.bounds()
        self.assertEqual(top_left.x, 1)
        self.assertEqual(top_left.y, 2)
        self.assertEqual(btm_right.x, 15)
        self.assertEqual(btm_right.y, 17)
コード例 #12
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)
コード例 #13
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)
コード例 #14
0
class ComponentParser(object):
    """I parse components from Fritzing libraries."""

    # The svg files in fritzing libraries are specified in pixels that
    # are 72dpi. The schematics are in 90dpi.
    svg_mult = 90.0 / 72.0

    def __init__(self, idref):
        self.component = Component(idref)
        self.next_pin_number = 0
        self.cid2termid = {}  # connid -> termid
        self.termid2pin = {}  # termid -> Pin
        self.terminals = set()
        self.width = 0.0
        self.height = 0.0

    def parse_fzp(self, fzp_file):
        """ Parse the Fritzing component file """

        tree = ElementTree(file=fzp_file)

        try:
            prefix = tree.find('label').text
        except AttributeError:
            pass
        else:
            self.component.add_attribute('_prefix', prefix)

        symbol = Symbol()
        self.component.add_symbol(symbol)

        self.body = Body()
        symbol.add_body(self.body)

        self.cid2termid.update(self.parse_terminals(tree))
        self.terminals.update(self.cid2termid.values())

        layers = tree.find('views/schematicView/layers')
        if layers is None:
            self.image = None
        else:
            self.image = layers.get('image')

    def connect_point(self, cid, inst, point):
        """ Given a connector id, instance id, and a NetPoint,
        add the appropriate ConnectedComponent to the point """

        termid = self.cid2termid.get(cid)
        pin = self.termid2pin.get(termid)

        if pin is not None:
            ccpt = ConnectedComponent(inst.instance_id, pin.pin_number)
            point.add_connected_component(ccpt)

    def get_next_pin_number(self):
        """ Return the next pin number """

        nextpn = self.next_pin_number
        self.next_pin_number += 1
        return str(nextpn)

    def parse_terminals(self, tree):
        """ Return a dictionary mapping connector id's to terminal id's """

        cid2termid = {}

        for conn in tree.findall('connectors/connector'):
            plug = conn.find('views/schematicView/p')
            if plug is None:
                continue

            termid = plug.get('terminalId')
            if termid is None:
                termid = plug.get('svgId')

            if termid is not None:
                cid2termid[conn.get('id')] = termid

        return cid2termid

    def parse_svg(self, svg_file):
        """ Parse the shapes and pins from an svg file """

        tree = ElementTree(file=svg_file)
        viewbox = tree.getroot().get('viewBox')

        if viewbox != None:
            self.width, self.height = [float(v) for v in viewbox.split()[-2:]]
            self.width *= self.svg_mult
            self.height *= self.svg_mult

        _iter = tree.getroot().getiterator()
        for element in _iter:
            for shape in self.parse_shapes(element):
                self.body.add_shape(shape)
                if element.get('id') in self.terminals:
                    pin = get_pin(shape)
                    if pin is not None:
                        pin.pin_number = self.get_next_pin_number()
                        self.termid2pin[element.get('id')] = pin
                        self.body.add_pin(pin)

    def parse_shapes(self, element):
        """ Parse a list of shapes from an svg element """

        tag = element.tag.rsplit('}', -1)[-1]

        if tag == 'circle':
            return self.parse_circle(element)
        elif tag == 'rect':
            return self.parse_rect(element)
        elif tag == 'line':
            return self.parse_line(element)
        elif tag == 'path':
            return self.parse_path(element)
        elif tag == 'polygon':
            return self.parse_polygon(element)
        elif tag == 'polyline':
            return self.parse_polyline(element)
        else:
            return []

    def parse_rect(self, rect):
        """ Parse a rect element """

        x, y = (get_x(rect, mult=self.svg_mult), get_y(rect,
                                                       mult=self.svg_mult))
        width, height = (get_length(rect, 'width', self.svg_mult),
                         get_length(rect, 'height', self.svg_mult))
        return [Rectangle(x, y, width, height)]

    def parse_line(self, rect):
        """ Parse a line element """

        return [
            Line((get_x(rect, 'x1',
                        self.svg_mult), get_y(rect, 'y1', self.svg_mult)),
                 (get_x(rect, 'x2',
                        self.svg_mult), get_y(rect, 'y2', self.svg_mult)))
        ]

    def parse_path(self, path):
        """ Parse a path element """

        return PathParser(path).parse()

    def parse_polygon(self, poly):
        """ Parse a polygon element """

        shape = Polygon()

        for point in poly.get('points', '').split():
            if point:
                x, y = point.split(',')
                shape.add_point(make_x(x, self.svg_mult),
                                make_y(y, self.svg_mult))

        if shape.points:
            shape.add_point(shape.points[0].x, shape.points[0].y)

        return [shape]

    def parse_polyline(self, poly):
        """ Parse a polyline element """

        shapes = []
        last_point = None

        for point in poly.get('points', '').split():
            if point:
                x, y = point.split(',')
                point = (make_x(x, self.svg_mult), make_y(y, self.svg_mult))
                if last_point is not None:
                    shapes.append(Line(last_point, point))
                last_point = point

        return shapes

    def parse_circle(self, circle):
        """ Parse a circle element """

        return [
            Circle(get_x(circle, 'cx', self.svg_mult),
                   get_y(circle, 'cy', self.svg_mult),
                   get_length(circle, 'r', self.svg_mult))
        ]
コード例 #15
0
class BodyTests(unittest.TestCase):
    """ The tests of the core module body feature """

    def setUp(self):
        """ Setup the test case. """
        self.bod = Body()

    def tearDown(self):
        """ Teardown the test case. """
        self.bod = Body()

    def test_create_new_body(self):
        """ Test the creation of a new empty body. """
        assert len(self.bod.shapes) == 0
        assert len(self.bod.pins) == 0

    def test_empty_bounds(self):
        '''Test that an empty body only bounds the local origin'''
        top_left, bottom_right = self.bod.bounds()
        self.assertEqual(top_left.x, 0)
        self.assertEqual(top_left.y, 0)
        self.assertEqual(bottom_right.x, 0)
        self.assertEqual(bottom_right.y, 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)

    def test_bounds_shapes(self):
        '''Test Body.bounds() when the body only consists of shapes'''
        shapes = [Shape() for i in range(4)]
        for i, shape in enumerate(shapes):
            bounds = [3, 3, 3, 3]
            bounds[i] = 2 * i
            mkbounds(shape, bounds[0], bounds[1], bounds[2], bounds[3])
            self.bod.add_shape(shape)

        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)

    def test_bounds_pins_shapes(self):
        '''Test Body.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)
コード例 #16
0
 def setUp(self):
     """ Setup the test case. """
     self.bod = Body()
コード例 #17
0
 def tearDown(self):
     """ Teardown the test case. """
     self.bod = Body()
コード例 #18
0
class ComponentParser(object):
    """I parse components from Fritzing libraries."""

    # The svg files in fritzing libraries are specified in pixels that
    # are 72dpi. The schematics are in 90dpi.
    svg_mult = 90.0 / 72.0

    def __init__(self, idref):
        self.component = Component(idref)
        self.next_pin_number = 0
        self.cid2termid = {} # connid -> termid
        self.termid2pin = {} # termid -> Pin
        self.terminals = set()
        self.width = 0.0
        self.height = 0.0


    def parse_fzp(self, fzp_file):
        """ Parse the Fritzing component file """

        tree = ElementTree(file=fzp_file)

        try:
            prefix = tree.find('label').text
        except AttributeError:
            pass
        else:
            self.component.add_attribute('_prefix', prefix)

        symbol = Symbol()
        self.component.add_symbol(symbol)

        self.body = Body()
        symbol.add_body(self.body)

        self.cid2termid.update(self.parse_terminals(tree))
        self.terminals.update(self.cid2termid.values())

        layers = tree.find('views/schematicView/layers')
        if layers is None:
            self.image = None
        else:
            self.image = layers.get('image')


    def connect_point(self, cid, inst, point):
        """ Given a connector id, instance id, and a NetPoint,
        add the appropriate ConnectedComponent to the point """

        termid = self.cid2termid.get(cid)
        pin = self.termid2pin.get(termid)

        if pin is not None:
            ccpt = ConnectedComponent(inst.instance_id, pin.pin_number)
            point.add_connected_component(ccpt)


    def get_next_pin_number(self):
        """ Return the next pin number """

        nextpn = self.next_pin_number
        self.next_pin_number += 1
        return str(nextpn)


    def parse_terminals(self, tree):
        """ Return a dictionary mapping connector id's to terminal id's """

        cid2termid = {}

        for conn in tree.findall('connectors/connector'):
            plug = conn.find('views/schematicView/p')
            if plug is None:
                continue

            termid = plug.get('terminalId')
            if termid is None:
                termid = plug.get('svgId')

            if termid is not None:
                cid2termid[conn.get('id')] = termid

        return cid2termid


    def parse_svg(self, svg_file):
        """ Parse the shapes and pins from an svg file """

        tree = ElementTree(file=svg_file)
        viewbox = tree.getroot().get('viewBox')

        if viewbox != None:
            self.width, self.height = [float(v) for v in viewbox.split()[-2:]]
            self.width *= self.svg_mult
            self.height *= self.svg_mult

        _iter = tree.getroot().getiterator()
        for element in _iter:
            for shape in self.parse_shapes(element):
                self.body.add_shape(shape)
                if element.get('id') in self.terminals:
                    pin = get_pin(shape)
                    if pin is not None:
                        pin.pin_number = self.get_next_pin_number()
                        self.termid2pin[element.get('id')] = pin
                        self.body.add_pin(pin)


    def parse_shapes(self, element):
        """ Parse a list of shapes from an svg element """

        tag = element.tag.rsplit('}', -1)[-1]

        if tag == 'circle':
            return self.parse_circle(element)
        elif tag == 'rect':
            return self.parse_rect(element)
        elif tag == 'line':
            return self.parse_line(element)
        elif tag == 'path':
            return self.parse_path(element)
        elif tag == 'polygon':
            return self.parse_polygon(element)
        elif tag == 'polyline':
            return self.parse_polyline(element)
        else:
            return []

    def parse_rect(self, rect):
        """ Parse a rect element """

        x, y = (get_x(rect, mult=self.svg_mult),
                get_y(rect, mult=self.svg_mult))
        width, height = (get_length(rect, 'width', self.svg_mult),
                         get_length(rect, 'height', self.svg_mult))
        return [Rectangle(x, y, width, height)]


    def parse_line(self, rect):
        """ Parse a line element """

        return [Line((get_x(rect, 'x1', self.svg_mult),
                      get_y(rect, 'y1', self.svg_mult)),
                     (get_x(rect, 'x2', self.svg_mult),
                      get_y(rect, 'y2', self.svg_mult)))]


    def parse_path(self, path):
        """ Parse a path element """

        return PathParser(path).parse()


    def parse_polygon(self, poly):
        """ Parse a polygon element """

        shape = Polygon()

        for point in poly.get('points', '').split():
            if point:
                x, y = point.split(',')
                shape.add_point(make_x(x, self.svg_mult),
                                make_y(y, self.svg_mult))

        if shape.points:
            shape.add_point(shape.points[0].x, shape.points[0].y)

        return [shape]


    def parse_polyline(self, poly):
        """ Parse a polyline element """

        shapes = []
        last_point = None

        for point in poly.get('points', '').split():
            if point:
                x, y = point.split(',')
                point = (make_x(x, self.svg_mult), make_y(y, self.svg_mult))
                if last_point is not None:
                    shapes.append(Line(last_point, point))
                last_point = point

        return shapes


    def parse_circle(self, circle):
        """ Parse a circle element """

        return [Circle(get_x(circle, 'cx', self.svg_mult),
                       get_y(circle, 'cy', self.svg_mult),
                       get_length(circle, 'r', self.svg_mult))]