Пример #1
0
 def getStyleString(self):
     return utils.dictToStyleText(self._style_dict)
Пример #2
0
    def _placeDrillIndex(self):
        """
        Adds a drill index
        """

        # Get the drills sheet / SVG layer
        drill_layer = self._layers['drills']['layer']
        ns = {'pcbmode':config.cfg['ns']['pcbmode'],
              'svg':config.cfg['ns']['svg']}
        drills = drill_layer.findall(".//*[@pcbmode:diameter]", namespaces=ns)

        drills_dict = {}
        longest_text = 0
        largest_drill = 0
        drill_count = 0
        for drill in drills:
            diameter = drill.get('{'+config.cfg['ns']['pcbmode']+'}diameter')
            diameter = round(float(diameter), 2)
            if diameter not in drills_dict:
                drills_dict[diameter] = 1
            else:
                drills_dict[diameter] += 1
            if diameter > largest_drill:
                largest_drill = diameter
            drill_count += 1

            if len(str(diameter)) > longest_text:
                longest_text = len(str(diameter))


        # Get location, or generate one
        try:
            location = config.brd['drill-index']['location']
        except:
            # If not location is specified, put the drill index at the
            # bottom left of the board. The 'gap' defines the extra
            # spcae between the top of the largest drill and the
            # board's edge
            gap = 2
            location = [-self._width/2, -(self._height/2+gap)]
        location = utils.toPoint(location)        

        # Create group for placing index
        transform = "translate(%s,%s)" % (location.x, config.cfg['invert-y']*location.y)
        group = et.SubElement(drill_layer, 'g',
                              transform=transform)
        group.set('{'+config.cfg['ns']['pcbmode']+'}type', 'drill-index')
        

        text_style_dict = config.stl['layout']['drill-index'].get('text')
        text_style = utils.dictToStyleText(text_style_dict)
 
        count_style_dict = config.stl['layout']['drill-index'].get('count-text')
        count_style = utils.dictToStyleText(count_style_dict)        

        count_style_dict['font-size'] /= 2
        drill_size_style = utils.dictToStyleText(count_style_dict)

        if drill_count == 0:
            text = 'No drills'
        elif drill_count == 1:
            text = '1 drill: '
        else:
            text = '%s drills: ' % drill_count
        t = et.SubElement(group, 'text',
                          x=str(0),
                          y=str(0),
                          style=text_style)
        t.text = text

        # "new line"
        location.y = -(largest_drill/2 + 1.5)

        # TODO: this hack'ish thing for aligning the text isn't going
        # to work when the font is changed in the stylesheet
        if float(longest_text*0.5) > largest_drill:
            location.x = longest_text*0.3
        else:
            location.x = largest_drill/2

        gap = 2

        for diameter in reversed(sorted(drills_dict)):
            path = svg.drillPath(diameter)
            transform = "translate(%s,%s)" % (location.x, config.cfg['invert-y']*location.y)
            element = et.SubElement(group, 'path',
                                    d=path,
                                    transform=transform)
            element.set("fill-rule", "evenodd")

            t = et.SubElement(group, 'text',
                              x=str(location.x),
                              y=str(-location.y),
                              dy="%s" % (config.cfg['invert-y']*0.25),
                              style=count_style)
            t.text = str(drills_dict[diameter])

            t = et.SubElement(group, 'text',
                              x=str(location.x),
                              y=str(-location.y),
                              dy="%s" % (config.cfg['invert-y']*-0.5),
                              style=drill_size_style)
            t.text = "%s mm" % diameter

            location.x += max(diameter, 2.5) 
Пример #3
0
    def _placeComponents(self, components, component_type, print_refdef=False):
        """
        """
        for component in components:
            shapes_dict = component.getShapes()
            location = component.getLocation()

            refdef = component.getRefdef()

            if print_refdef == True:
                print refdef,

            # If the component is placed on the bottom layer we need
            # to invert the shapes AND their 'x' coordinate.  This is
            # done using the 'invert' indicator set below
            placement_layer = component.getPlacementLayer()
            if placement_layer == 'bottom':
                invert = True
            else:
                invert = False

            for pcb_layer in utils.getSurfaceLayers():

                there_are_pours = utils.checkForPoursInLayer(pcb_layer)

                # Copper
                shapes = shapes_dict['copper'][pcb_layer]

                if len(shapes) > 0:

                    svg_layer = self._layers[pcb_layer]['copper']['pads'][
                        'layer']

                    transform = "translate(%s,%s)" % (
                        location[0], config.cfg['invert-y'] * location[1])

                    group = et.SubElement(svg_layer, 'g', transform=transform)

                    if component_type == 'components':
                        group.set(
                            '{' + config.cfg['ns']['pcbmode'] + '}refdef',
                            component.getRefdef())
                    elif component_type == 'vias':
                        group.set('{' + config.cfg['ns']['pcbmode'] + '}type',
                                  'via')
                        group.set('{' + config.cfg['ns']['pcbmode'] + '}via',
                                  component.getFootprintName())
                    else:
                        pass

                    for shape in shapes:
                        place.placeShape(shape, group, invert)
                        if there_are_pours == True:
                            mask_group = et.SubElement(self._masks[pcb_layer],
                                                       'g',
                                                       transform=transform)
                            self._placeMask(mask_group,
                                            shape,
                                            'pad',
                                            original=False,
                                            mirror=invert)

                    # Add pin labels

                    # There's a bit of a hack here that won't work in
                    # all possible cases (where pads are placed on
                    # bottom layer in a component that has pins placed
                    # both on the top and on the bottom -- a rare
                    # case). Good enough for now

                    labels = shapes_dict['pin-labels']['top']  #[pcb_layer]
                    if labels != []:
                        style = utils.dictToStyleText(
                            config.stl['layout']['board']['pad-labels'])
                        label_group = et.SubElement(
                            group,
                            'g',
                            transform="rotate(%s)" %
                            (((1, -1)[invert]) * component.getRotation()),
                            style=style)
                        for label in labels:
                            t = et.SubElement(label_group,
                                              'text',
                                              x=str(((1, -1)[invert]) *
                                                    label['location'][0]),
                                              y=str(config.cfg['invert-y'] *
                                                    label['location'][1]))
                            t.text = label['text']

                # Soldermask
                shapes = shapes_dict['soldermask'][pcb_layer]
                if len(shapes) > 0:
                    svg_layer = self._layers[pcb_layer]['soldermask']['layer']
                    transform = "translate(%s,%s)" % (
                        location[0], config.cfg['invert-y'] * location[1])
                    group = et.SubElement(svg_layer, 'g', transform=transform)
                    group.set('{' + config.cfg['ns']['pcbmode'] + '}type',
                              'component-shapes')
                    for shape in shapes:
                        placed_element = place.placeShape(shape, group, invert)

                    # Solderpaste
                    shapes = shapes_dict['solderpaste'][pcb_layer]
                    svg_layer = self._layers[pcb_layer]['solderpaste']['layer']
                    transform = "translate(%s,%s)" % (
                        location[0], config.cfg['invert-y'] * location[1])
                    group = et.SubElement(svg_layer, 'g', transform=transform)
                    group.set('{' + config.cfg['ns']['pcbmode'] + '}type',
                              'component-shapes')
                    for shape in shapes:
                        placed_element = place.placeShape(shape, group, invert)

                # Silkscreen
                shapes = shapes_dict['silkscreen'][pcb_layer]
                if len(shapes) > 0:
                    svg_layer = self._layers[pcb_layer]['silkscreen']['layer']
                    transform = "translate(%s,%s)" % (
                        location[0], config.cfg['invert-y'] * location[1])
                    shape_group = et.SubElement(svg_layer,
                                                'g',
                                                transform=transform)
                    shape_group.set(
                        '{' + config.cfg['ns']['pcbmode'] + '}type',
                        'component-shapes')

                    for shape in shapes:
                        # Refdefs need to be in their own groups so that their
                        # location can later be extracted, hence this...
                        try:
                            is_refdef = getattr(shape, 'is_refdef')
                        except:
                            is_refdef = False

                        if is_refdef == True:
                            refdef_group = et.SubElement(svg_layer,
                                                         'g',
                                                         transform=transform)
                            refdef_group.set(
                                '{' + config.cfg['ns']['pcbmode'] + '}type',
                                'refdef')
                            refdef_group.set(
                                '{' + config.cfg['ns']['pcbmode'] + '}refdef',
                                refdef)
                            placed_element = place.placeShape(
                                shape, refdef_group, invert)
                        else:
                            placed_element = place.placeShape(
                                shape, shape_group, invert)

                # Assembly
                shapes = shapes_dict['assembly'][pcb_layer]
                if len(shapes) > 0:
                    svg_layer = self._layers[pcb_layer]['assembly']['layer']
                    transform = "translate(%s,%s)" % (
                        location[0], config.cfg['invert-y'] * location[1])
                    group = et.SubElement(svg_layer, 'g', transform=transform)
                    for shape in shapes:
                        placed_element = place.placeShape(shape, group, invert)

                # Drills
                shapes = shapes_dict['drills'][pcb_layer]
                if len(shapes) > 0:
                    svg_layer = self._layers['drills']['layer']
                    transform = "translate(%s,%s)" % (
                        location[0], config.cfg['invert-y'] * location[1])
                    group = et.SubElement(svg_layer, 'g', transform=transform)
                    group.set('{' + config.cfg['ns']['pcbmode'] + '}type',
                              'component-shapes')
                    for shape in shapes:
                        placed_element = place.placeShape(shape, group, invert)
                        placed_element.set(
                            '{' + config.cfg['ns']['pcbmode'] + '}diameter',
                            str(shape.getDiameter()))
Пример #4
0
    def _placeComponents(self, components, component_type, print_refdef=False):
        """
        """
        for component in components:
            shapes_dict = component.getShapes()
            location = component.getLocation()

            # If the component is placed on the bottom layer we need
            # to invert the shapes AND their 'x' coordinate.  This is
            # sone using the 'invert' indicator set below
            refdef = component.getRefdef()

            if print_refdef == True:
                print refdef,

            placement_layer = component.getPlacementLayer()
            if placement_layer == 'bottom':
                invert = True
            else:
                invert = False

            for pcb_layer in utils.getSurfaceLayers():

                there_are_pours = utils.checkForPoursInLayer(pcb_layer)

                # Copper
                shapes = shapes_dict['copper'][pcb_layer]
                if len(shapes) > 0:
                    svg_layer = self._layers[pcb_layer]['copper']['pads'][
                        'layer']

                    transform = "translate(%s,%s)" % (
                        location[0], config.cfg['invert-y'] * location[1])
                    group = et.SubElement(svg_layer, 'g', transform=transform)

                    if component_type == 'components':
                        group.set(
                            '{' + config.cfg['ns']['pcbmode'] + '}refdef',
                            component.getRefdef())
                    elif component_type == 'vias':
                        group.set('{' + config.cfg['ns']['pcbmode'] + '}type',
                                  'via')
                        group.set('{' + config.cfg['ns']['pcbmode'] + '}via',
                                  component.getFootprintName())
                    else:
                        pass

                    for shape in shapes:
                        place.placeShape(shape, group)
                        if there_are_pours == True:
                            mask_group = et.SubElement(self._masks[pcb_layer],
                                                       'g',
                                                       transform=transform)
                            self._placeMask(mask_group, shape, 'pad')

                    # Add pin labels
                    labels = shapes_dict['pin-labels'][pcb_layer]
                    if labels != []:
                        style = utils.dictToStyleText(
                            config.stl['layout']['board']['pad-labels'])
                        label_group = et.SubElement(group,
                                                    'g',
                                                    transform="rotate(%s)" %
                                                    component.getRotation(),
                                                    style=style)
                        for label in labels:
                            t = et.SubElement(
                                label_group,
                                'text',
                                x=str(label['location'][0]),
                                # TODO: get rid of this hack
                                y=str(-label['location'][1]))
                            #y=str(-pin_location.y + pad_numbers_font_size/3),
                            #refdef=self._refdef)
                            t.text = label['text']

                # Soldermask
                shapes = shapes_dict['soldermask'][pcb_layer]
                if len(shapes) > 0:
                    svg_layer = self._layers[pcb_layer]['soldermask']['layer']
                    transform = "translate(%s,%s)" % (
                        location[0], config.cfg['invert-y'] * location[1])
                    group = et.SubElement(svg_layer, 'g', transform=transform)
                    group.set('{' + config.cfg['ns']['pcbmode'] + '}type',
                              'component-shapes')
                    for shape in shapes:
                        placed_element = place.placeShape(shape, group)

                    # Solderpaste
                    shapes = shapes_dict['solderpaste'][pcb_layer]
                    svg_layer = self._layers[pcb_layer]['solderpaste']['layer']
                    transform = "translate(%s,%s)" % (
                        location[0], config.cfg['invert-y'] * location[1])
                    group = et.SubElement(svg_layer, 'g', transform=transform)
                    group.set('{' + config.cfg['ns']['pcbmode'] + '}type',
                              'component-shapes')
                    for shape in shapes:
                        placed_element = place.placeShape(shape, group)

                # Silkscreen
                shapes = shapes_dict['silkscreen'][pcb_layer]
                if len(shapes) > 0:
                    svg_layer = self._layers[pcb_layer]['silkscreen']['layer']
                    transform = "translate(%s,%s)" % (
                        location[0], config.cfg['invert-y'] * location[1])
                    shape_group = et.SubElement(svg_layer,
                                                'g',
                                                transform=transform)
                    shape_group.set(
                        '{' + config.cfg['ns']['pcbmode'] + '}type',
                        'component-shapes')

                    for shape in shapes:
                        # Refdefs need to be in their own groups so that their
                        # location can later be extracted, hence this...
                        try:
                            is_refdef = getattr(shape, 'is_refdef')
                        except:
                            is_refdef = False

                        if is_refdef == True:
                            refdef_group = et.SubElement(svg_layer,
                                                         'g',
                                                         transform=transform)
                            refdef_group.set(
                                '{' + config.cfg['ns']['pcbmode'] + '}type',
                                'refdef')
                            refdef_group.set(
                                '{' + config.cfg['ns']['pcbmode'] + '}refdef',
                                refdef)
                            placed_element = place.placeShape(
                                shape, refdef_group)
                        else:
                            placed_element = place.placeShape(
                                shape, shape_group)

                # Assembly
                shapes = shapes_dict['assembly'][pcb_layer]
                if len(shapes) > 0:
                    svg_layer = self._layers[pcb_layer]['assembly']['layer']
                    transform = "translate(%s,%s)" % (
                        location[0], config.cfg['invert-y'] * location[1])
                    group = et.SubElement(svg_layer, 'g', transform=transform)
                    for shape in shapes:
                        placed_element = place.placeShape(shape, group)

                # Drills
                shapes = shapes_dict['drills'][pcb_layer]
                if len(shapes) > 0:
                    svg_layer = self._layers['drills']['layer']
                    transform = "translate(%s,%s)" % (
                        location[0], config.cfg['invert-y'] * location[1])
                    group = et.SubElement(svg_layer, 'g', transform=transform)
                    group.set('{' + config.cfg['ns']['pcbmode'] + '}type',
                              'component-shapes')
                    for shape in shapes:
                        placed_element = place.placeShape(shape, group)
                        placed_element.set(
                            '{' + config.cfg['ns']['pcbmode'] + '}diameter',
                            str(shape.getDiameter()))
Пример #5
0
    def _placeComponents(self, components, component_type, print_refdef=False):
        """
        Places the component on the board.  

        'component_type' is the content of the 'type' fiels of the
        placed group. This is used by the extractor to identify the
        type of component ('component', 'via', 'shape')
        """

        htmlpar = HTMLParser.HTMLParser()

        for component in components:
            shapes_dict = component.getShapes()
            location = component.getLocation()
            rotation = component.getRotation()
            refdef = component.getRefdef()

            if print_refdef == True:
                print refdef,

            # If the component is placed on the bottom layer we need
            # to invert the shapes AND their 'x' coordinate.  This is
            # done using the 'invert' indicator set below
            placement_layer = component.getPlacementLayer()
            if placement_layer == 'bottom':
                invert = True
            else:
                invert = False

            for pcb_layer in config.stk['layer-names']:

                there_are_pours = utils.checkForPoursInLayer(pcb_layer)

                # Copper
                shapes = shapes_dict['conductor'].get(pcb_layer) or []

                if len(shapes) > 0:

                    svg_layer = self._layers[pcb_layer]['conductor']['pads']['layer']
     
                    transform = "translate(%s,%s)" % (location[0],
                                                      config.cfg['invert-y']*location[1])

                    shape_group = et.SubElement(svg_layer, 'g', 
                                                transform=transform)


                    shape_group.set('{'+config.cfg['ns']['pcbmode']+'}type', component_type)
                    # Add the reference designator as well if it's a
                    # 'component'
                    if component_type == 'component':
                        shape_group.set('{'+config.cfg['ns']['pcbmode']+'}refdef', component.getRefdef())

                    style = utils.dictToStyleText(config.stl['layout']['conductor']['pads']['labels'])
                    label_group = et.SubElement(shape_group, 'g', style=style)

                    for shape in shapes:
                        place.placeShape(shape, shape_group, invert)

                        # Add pin labels
                        # TODO: This isn't perfect, but good enough for now
                        label = shape.getLabel()
                        if label != None:
                            label_location = shape.getLocation()
                            label_rotation = shape.getRotation()
                            label_transform = "rotate(%s)" % label_rotation
                            t = et.SubElement(label_group, 'text',
                                              x=str(((1,-1)[invert])*label_location.x),
                                              y=str(config.cfg['invert-y']*label_location.y),
                                              transform=label_transform)
                            t.text = label


                        if there_are_pours == True:
                            mask_group = et.SubElement(self._masks[pcb_layer], 'g', 
                                                       transform=transform)
                            self._placeMask(mask_group, 
                                            shape,
                                            'pad',
                                            original=False,
                                            mirror=invert)


                # Pours
                shapes = shapes_dict['pours'].get(pcb_layer) or []
                try:
                    svg_layer = self._layers[pcb_layer]['conductor']['pours']['layer']
                    shape_group = et.SubElement(svg_layer, 'g',
                                                mask='url(#mask-%s)' % pcb_layer)
                except:
                    svg_layer = None

                if len(shapes) > 0 and svg_layer != None:
                    transform = "translate(%s,%s)" % (location[0],
                                                      config.cfg['invert-y']*location[1])
                    group = et.SubElement(shape_group, 'g', transform=transform)
                    group.set('{'+config.cfg['ns']['pcbmode']+'}type', 'pours')
                    for shape in shapes:
                        placed_element = place.placeShape(shape, group, invert)




                # Soldermask
                shapes = shapes_dict['soldermask'].get(pcb_layer) or []
                try:
                    svg_layer = self._layers[pcb_layer]['soldermask']['layer']
                except:
                    svg_layer = None

                if len(shapes) > 0 and svg_layer != None:
                    transform = "translate(%s,%s)" % (location[0],
                                                      config.cfg['invert-y']*location[1])
                    group = et.SubElement(svg_layer, 'g', transform=transform)
                    group.set('{'+config.cfg['ns']['pcbmode']+'}type', 'component-shapes')
                    for shape in shapes:
                        placed_element = place.placeShape(shape, group, invert)

     
                # Solderpaste
                shapes = shapes_dict['solderpaste'].get(pcb_layer) or []
                try:
                    svg_layer = self._layers[pcb_layer]['solderpaste']['layer']
                except:
                    svg_layer = None

                if len(shapes) > 0 and svg_layer != None:
                    transform = "translate(%s,%s)" % (location[0],
                                                      config.cfg['invert-y']*location[1])
                    group = et.SubElement(svg_layer, 'g', transform=transform)
                    group.set('{'+config.cfg['ns']['pcbmode']+'}type', 'component-shapes')
                    for shape in shapes:
                        placed_element = place.placeShape(shape, group, invert)



                # Silkscreen
                shapes = shapes_dict['silkscreen'].get(pcb_layer) or []
                try:
                    svg_layer = self._layers[pcb_layer]['silkscreen']['layer']
                except:
                    svg_layer = None

                if len(shapes) > 0 and svg_layer != None:
                    transform = "translate(%s,%s)" % (location[0],
                                                      config.cfg['invert-y']*location[1])
                    shape_group = et.SubElement(svg_layer, 'g', transform=transform)
                    shape_group.set('{'+config.cfg['ns']['pcbmode']+'}type', 'component-shapes')
     
                    for shape in shapes:
                        # Refdefs need to be in their own groups so that their
                        # location can later be extracted, hence this...
                        try:
                            is_refdef = getattr(shape, 'is_refdef')
                        except:
                            is_refdef = False

                        if is_refdef == True:
                            # Shapes don't need to have silkscreen
                            # reference designators
                            if component_type != 'shape':
                                refdef_group = et.SubElement(svg_layer, 'g', transform=transform)
                                refdef_group.set('{'+config.cfg['ns']['pcbmode']+'}type', 'refdef')
                                refdef_group.set('{'+config.cfg['ns']['pcbmode']+'}refdef', refdef)
                                placed_element = place.placeShape(shape, refdef_group, invert)
                        else:
                            placed_element = place.placeShape(shape, shape_group, invert)



                # Assembly
                shapes = shapes_dict['assembly'].get(pcb_layer) or []
                try:
                    svg_layer = self._layers[pcb_layer]['assembly']['layer']
                except:
                    svg_layer = None

                if len(shapes) > 0 and svg_layer != None: 
                    transform = "translate(%s,%s)" % (location[0],
                                                      config.cfg['invert-y']*location[1])
                    group = et.SubElement(svg_layer, 'g', transform=transform)
                    for shape in shapes:
                        placed_element = place.placeShape(shape, group, invert)





                # Drills
                shapes = shapes_dict['drills'].get(pcb_layer) or []
                if len(shapes) > 0:
                    svg_layer = self._layers['drills']['layer']
                    transform = "translate(%s,%s)" % (location[0],
                                                      config.cfg['invert-y']*location[1])
                    group = et.SubElement(svg_layer, 'g', transform=transform)
                    group.set('{'+config.cfg['ns']['pcbmode']+'}type', 'component-shapes')
                    for shape in shapes:
                        placed_element = place.placeShape(shape, group, invert)
                        placed_element.set('{'+config.cfg['ns']['pcbmode']+'}diameter',
                                           str(shape.getDiameter()))


                
            # Place component origin marker
            svg_layer = self._layers[placement_layer]['placement']['layer']

            # Here pcb_layer may not exist for components that define
            # shapes for internal layers but only surface layers are
            # defined in the stackup
            try:
                group = et.SubElement(svg_layer, 'g', transform=transform)
            except:
                return

            group.set('{'+config.cfg['ns']['pcbmode']+'}type', component_type)
            group.set('{'+config.cfg['ns']['pcbmode']+'}footprint', component.getFootprintName())
            if (component_type == 'component') or (component_type == 'shape'):
                group.set('{'+config.cfg['ns']['pcbmode']+'}refdef', refdef)

            path = svg.placementMarkerPath()
            transform = "translate(%s,%s)" % (location[0],
                                              config.cfg['invert-y']*location[1])

            if placement_layer == 'bottom':
                rotation *= -1

            marker_element = et.SubElement(group, 'path',
                                           d=path,
                                           transform="rotate(%s)" % rotation)

            if (component_type == 'component'):
                style = utils.dictToStyleText(config.stl['layout']['placement']['text'])
     
                t = et.SubElement(group, 'text', x="0", y="-0.17", style=style)
                ts = et.SubElement(t, 'tspan', x="0", dy="0.1")
                ts.text = "%s" % (refdef)
                ts = et.SubElement(t, 'tspan', x="0", dy="0.1")
                ts.text = htmlpar.unescape("%s°" % (rotation))
                ts = et.SubElement(t, 'tspan', x="0", dy="0.1")
                ts.text = "[%.2f,%.2f]" % (location[0], location[1])
            elif (component_type == 'shape'):
                style = utils.dictToStyleText(config.stl['layout']['placement']['text'])
     
                t = et.SubElement(group, 'text', x="0", y="-0.17", style=style)
                ts = et.SubElement(t, 'tspan', x="0", dy="0.1")
                ts.text = "%s" % (refdef)
                ts = et.SubElement(t, 'tspan', x="0", dy="0.1")
                ts.text = htmlpar.unescape("%s°" % (rotation))
                ts = et.SubElement(t, 'tspan', x="0", dy="0.1")
                ts.text = "[%.2f,%.2f]" % (location[0], location[1])
            elif (component_type == 'via'):
                style = utils.dictToStyleText(config.stl['layout']['placement']['text'])
     
                t = et.SubElement(group, 'text', x="0", y="-0.11", style=style)
                ts = et.SubElement(t, 'tspan', x="0", dy="0.1")
                ts.text = htmlpar.unescape("%s°" % (rotation))
                ts = et.SubElement(t, 'tspan', x="0", dy="0.1")
                ts.text = "[%.2f,%.2f]" % (location[0], location[1])
            else:
                continue
Пример #6
0
    def _placeComponents(self, components, component_type, print_refdef=False):
        """
        """
        for component in components:
            shapes_dict = component.getShapes()
            location = component.getLocation()

            refdef = component.getRefdef()

            if print_refdef == True:
                print refdef,

            # If the component is placed on the bottom layer we need
            # to invert the shapes AND their 'x' coordinate.  This is
            # done using the 'invert' indicator set below
            placement_layer = component.getPlacementLayer()
            if placement_layer == 'bottom':
                invert = True
            else:
                invert = False

            for pcb_layer in utils.getSurfaceLayers():

                there_are_pours = utils.checkForPoursInLayer(pcb_layer)

                # Copper
                shapes = shapes_dict['copper'][pcb_layer]

                if len(shapes) > 0:

                    svg_layer = self._layers[pcb_layer]['copper']['pads']['layer']
     
                    transform = "translate(%s,%s)" % (location[0],
                                                      config.cfg['invert-y']*location[1])

                    group = et.SubElement(svg_layer, 'g', 
                                          transform=transform)

                    if component_type == 'components':
                        group.set('{'+config.cfg['ns']['pcbmode']+'}refdef', component.getRefdef())
                    elif component_type == 'vias':
                        group.set('{'+config.cfg['ns']['pcbmode']+'}type', 'via')
                        group.set('{'+config.cfg['ns']['pcbmode']+'}via', component.getFootprintName())
                    else:
                        pass

                    for shape in shapes:
                        place.placeShape(shape, group, invert)
                        if there_are_pours == True:
                            mask_group = et.SubElement(self._masks[pcb_layer], 'g', 
                                                       transform=transform)
                            self._placeMask(mask_group, 
                                            shape,
                                            'pad',
                                            original=False,
                                            mirror=invert)

                    # Add pin labels 

                    # There's a bit of a hack here that won't work in
                    # all possible cases (where pads are placed on
                    # bottom layer in a component that has pins placed
                    # both on the top and on the bottom -- a rare
                    # case). Good enough for now

                    labels = shapes_dict['pin-labels']['top']#[pcb_layer]
                    if labels != []:
                        style = utils.dictToStyleText(config.stl['layout']['board']['pad-labels'])
                        label_group = et.SubElement(group, 'g', 
                                                    transform="rotate(%s)" % (((1,-1)[invert])*component.getRotation()),
                                                    style=style)
                        for label in labels:
                            t = et.SubElement(label_group, 'text',
                                              x=str(((1,-1)[invert])*label['location'][0]),
                                              y=str(config.cfg['invert-y']*label['location'][1]))
                            t.text = label['text']





                # Soldermask
                shapes = shapes_dict['soldermask'][pcb_layer]
                if len(shapes) > 0:
                    svg_layer = self._layers[pcb_layer]['soldermask']['layer']
                    transform = "translate(%s,%s)" % (location[0],
                                                      config.cfg['invert-y']*location[1])
                    group = et.SubElement(svg_layer, 'g', transform=transform)
                    group.set('{'+config.cfg['ns']['pcbmode']+'}type', 'component-shapes')
                    for shape in shapes:
                        placed_element = place.placeShape(shape, group, invert)
     
                    # Solderpaste
                    shapes = shapes_dict['solderpaste'][pcb_layer]
                    svg_layer = self._layers[pcb_layer]['solderpaste']['layer']
                    transform = "translate(%s,%s)" % (location[0],
                                                      config.cfg['invert-y']*location[1])
                    group = et.SubElement(svg_layer, 'g', transform=transform)
                    group.set('{'+config.cfg['ns']['pcbmode']+'}type', 'component-shapes')
                    for shape in shapes:
                        placed_element = place.placeShape(shape, group, invert)


                # Silkscreen
                shapes = shapes_dict['silkscreen'][pcb_layer]
                if len(shapes) > 0:
                    svg_layer = self._layers[pcb_layer]['silkscreen']['layer']
                    transform = "translate(%s,%s)" % (location[0],
                                                      config.cfg['invert-y']*location[1])
                    shape_group = et.SubElement(svg_layer, 'g', transform=transform)
                    shape_group.set('{'+config.cfg['ns']['pcbmode']+'}type', 'component-shapes')
     
                    for shape in shapes:
                        # Refdefs need to be in their own groups so that their
                        # location can later be extracted, hence this...
                        try:
                            is_refdef = getattr(shape, 'is_refdef')
                        except:
                            is_refdef = False

                        if is_refdef == True:
                            refdef_group = et.SubElement(svg_layer, 'g', transform=transform)
                            refdef_group.set('{'+config.cfg['ns']['pcbmode']+'}type', 'refdef')
                            refdef_group.set('{'+config.cfg['ns']['pcbmode']+'}refdef', refdef)
                            placed_element = place.placeShape(shape, refdef_group, invert)
                        else:
                            placed_element = place.placeShape(shape, shape_group, invert)


                # Assembly
                shapes = shapes_dict['assembly'][pcb_layer]
                if len(shapes) > 0: 
                    svg_layer = self._layers[pcb_layer]['assembly']['layer']
                    transform = "translate(%s,%s)" % (location[0],
                                                      config.cfg['invert-y']*location[1])
                    group = et.SubElement(svg_layer, 'g', transform=transform)
                    for shape in shapes:
                        placed_element = place.placeShape(shape, group, invert)

                # Drills
                shapes = shapes_dict['drills'][pcb_layer]
                if len(shapes) > 0:
                    svg_layer = self._layers['drills']['layer']
                    transform = "translate(%s,%s)" % (location[0],
                                                      config.cfg['invert-y']*location[1])
                    group = et.SubElement(svg_layer, 'g', transform=transform)
                    group.set('{'+config.cfg['ns']['pcbmode']+'}type', 'component-shapes')
                    for shape in shapes:
                        placed_element = place.placeShape(shape, group)
                        placed_element.set('{'+config.cfg['ns']['pcbmode']+'}diameter',
                                           str(shape.getDiameter()))
Пример #7
0
 def getStyleString(self):
     return utils.dictToStyleText(self._style_dict)
Пример #8
0
    def _placeDrillIndex(self):
        """
        Adds a drill index
        """

        # Get the drills sheet / SVG layer
        drill_layer = self._layers['drills']['layer']
        ns = {
            'pcbmode': config.cfg['ns']['pcbmode'],
            'svg': config.cfg['ns']['svg']
        }
        drills = drill_layer.findall(".//*[@pcbmode:diameter]", namespaces=ns)

        drills_dict = {}
        longest_text = 0
        largest_drill = 0
        drill_count = 0
        for drill in drills:
            diameter = drill.get('{' + config.cfg['ns']['pcbmode'] +
                                 '}diameter')
            diameter = round(float(diameter), 2)
            if diameter not in drills_dict:
                drills_dict[diameter] = 1
            else:
                drills_dict[diameter] += 1
            if diameter > largest_drill:
                largest_drill = diameter
            drill_count += 1

            if len(str(diameter)) > longest_text:
                longest_text = len(str(diameter))

        # Get location, or generate one
        try:
            location = config.brd['drill-index']['location']
        except:
            # If not location is specified, put the drill index at the
            # bottom left of the board. The 'gap' defines the extra
            # spcae between the top of the largest drill and the
            # board's edge
            gap = 2
            location = [-self._width / 2, -(self._height / 2 + gap)]
        location = utils.toPoint(location)

        # Create group for placing index
        transform = "translate(%s,%s)" % (location.x,
                                          config.cfg['invert-y'] * location.y)
        group = et.SubElement(drill_layer, 'g', transform=transform)
        group.set('{' + config.cfg['ns']['pcbmode'] + '}type', 'drill-index')

        text_style_dict = config.stl['layout']['drill-index'].get('text')
        text_style = utils.dictToStyleText(text_style_dict)

        count_style_dict = config.stl['layout']['drill-index'].get(
            'count-text')
        count_style = utils.dictToStyleText(count_style_dict)

        count_style_dict['font-size'] /= 2
        drill_size_style = utils.dictToStyleText(count_style_dict)

        if drill_count == 0:
            text = 'No drills'
        elif drill_count == 1:
            text = '1 drill: '
        else:
            text = '%s drills: ' % drill_count
        t = et.SubElement(group, 'text', x=str(0), y=str(0), style=text_style)
        t.text = text

        # "new line"
        location.y = -(largest_drill / 2 + 1.5)

        # TODO: this hack'ish thing for aligning the text isn't going
        # to work when the font is changed in the stylesheet
        if float(longest_text * 0.5) > largest_drill:
            location.x = longest_text * 0.3
        else:
            location.x = largest_drill / 2

        gap = 2

        for diameter in reversed(sorted(drills_dict)):
            path = svg.drillPath(diameter)
            transform = "translate(%s,%s)" % (
                location.x, config.cfg['invert-y'] * location.y)
            element = et.SubElement(group, 'path', d=path, transform=transform)
            element.set("fill-rule", "evenodd")

            t = et.SubElement(group,
                              'text',
                              x=str(location.x),
                              y=str(-location.y),
                              dy="%s" % (config.cfg['invert-y'] * 0.25),
                              style=count_style)
            t.text = str(drills_dict[diameter])

            t = et.SubElement(group,
                              'text',
                              x=str(location.x),
                              y=str(-location.y),
                              dy="%s" % (config.cfg['invert-y'] * -0.5),
                              style=drill_size_style)
            t.text = "%s mm" % diameter

            location.x += max(diameter, 2.5)
Пример #9
0
    def _placeComponents(self, components, component_type, print_refdef=False):
        """
        Places the component on the board.  

        'component_type' is the content of the 'type' fiels of the
        placed group. This is used by the extractor to identify the
        type of component ('component', 'via', 'shape')
        """

        htmlpar = HTMLParser.HTMLParser()

        for component in components:
            shapes_dict = component.getShapes()
            location = component.getLocation()
            rotation = component.getRotation()
            refdef = component.getRefdef()

            if print_refdef == True:
                print refdef,

            # If the component is placed on the bottom layer we need
            # to invert the shapes AND their 'x' coordinate.  This is
            # done using the 'invert' indicator set below
            placement_layer = component.getPlacementLayer()
            if placement_layer == 'bottom':
                invert = True
            else:
                invert = False

            for pcb_layer in config.stk['layer-names']:

                there_are_pours = utils.checkForPoursInLayer(pcb_layer)

                # Copper
                shapes = shapes_dict['conductor'].get(pcb_layer) or []

                if len(shapes) > 0:

                    svg_layer = self._layers[pcb_layer]['conductor']['pads'][
                        'layer']

                    transform = "translate(%s,%s)" % (
                        location[0], config.cfg['invert-y'] * location[1])

                    shape_group = et.SubElement(svg_layer,
                                                'g',
                                                transform=transform)

                    shape_group.set(
                        '{' + config.cfg['ns']['pcbmode'] + '}type',
                        component_type)
                    # Add the reference designator as well if it's a
                    # 'component'
                    if component_type == 'component':
                        shape_group.set(
                            '{' + config.cfg['ns']['pcbmode'] + '}refdef',
                            component.getRefdef())

                    style = utils.dictToStyleText(
                        config.stl['layout']['conductor']['pads']['labels'])
                    label_group = et.SubElement(shape_group, 'g', style=style)

                    for shape in shapes:
                        place.placeShape(shape, shape_group, invert)

                        # Add pin labels
                        # TODO: This isn't perfect, but good enough for now
                        label = shape.getLabel()
                        if label != None:
                            label_location = shape.getLocation()
                            label_rotation = shape.getRotation()
                            label_transform = "rotate(%s)" % label_rotation
                            t = et.SubElement(label_group,
                                              'text',
                                              x=str(((1, -1)[invert]) *
                                                    label_location.x),
                                              y=str(config.cfg['invert-y'] *
                                                    label_location.y),
                                              transform=label_transform)
                            t.text = label

                        if there_are_pours == True:
                            mask_group = et.SubElement(self._masks[pcb_layer],
                                                       'g',
                                                       transform=transform)
                            self._placeMask(mask_group,
                                            shape,
                                            'pad',
                                            original=False,
                                            mirror=invert)

                # Pours
                shapes = shapes_dict['pours'].get(pcb_layer) or []
                try:
                    svg_layer = self._layers[pcb_layer]['conductor']['pours'][
                        'layer']
                    shape_group = et.SubElement(svg_layer,
                                                'g',
                                                mask='url(#mask-%s)' %
                                                pcb_layer)
                except:
                    svg_layer = None

                if len(shapes) > 0 and svg_layer != None:
                    transform = "translate(%s,%s)" % (
                        location[0], config.cfg['invert-y'] * location[1])
                    group = et.SubElement(shape_group,
                                          'g',
                                          transform=transform)
                    group.set('{' + config.cfg['ns']['pcbmode'] + '}type',
                              'pours')
                    for shape in shapes:
                        placed_element = place.placeShape(shape, group, invert)

                # Soldermask
                shapes = shapes_dict['soldermask'].get(pcb_layer) or []
                try:
                    svg_layer = self._layers[pcb_layer]['soldermask']['layer']
                except:
                    svg_layer = None

                if len(shapes) > 0 and svg_layer != None:
                    transform = "translate(%s,%s)" % (
                        location[0], config.cfg['invert-y'] * location[1])
                    group = et.SubElement(svg_layer, 'g', transform=transform)
                    group.set('{' + config.cfg['ns']['pcbmode'] + '}type',
                              'component-shapes')
                    for shape in shapes:
                        placed_element = place.placeShape(shape, group, invert)

                # Solderpaste
                shapes = shapes_dict['solderpaste'].get(pcb_layer) or []
                try:
                    svg_layer = self._layers[pcb_layer]['solderpaste']['layer']
                except:
                    svg_layer = None

                if len(shapes) > 0 and svg_layer != None:
                    transform = "translate(%s,%s)" % (
                        location[0], config.cfg['invert-y'] * location[1])
                    group = et.SubElement(svg_layer, 'g', transform=transform)
                    group.set('{' + config.cfg['ns']['pcbmode'] + '}type',
                              'component-shapes')
                    for shape in shapes:
                        placed_element = place.placeShape(shape, group, invert)

                # Silkscreen
                shapes = shapes_dict['silkscreen'].get(pcb_layer) or []
                try:
                    svg_layer = self._layers[pcb_layer]['silkscreen']['layer']
                except:
                    svg_layer = None

                if len(shapes) > 0 and svg_layer != None:
                    transform = "translate(%s,%s)" % (
                        location[0], config.cfg['invert-y'] * location[1])
                    shape_group = et.SubElement(svg_layer,
                                                'g',
                                                transform=transform)
                    shape_group.set(
                        '{' + config.cfg['ns']['pcbmode'] + '}type',
                        'component-shapes')

                    for shape in shapes:
                        # Refdefs need to be in their own groups so that their
                        # location can later be extracted, hence this...
                        try:
                            is_refdef = getattr(shape, 'is_refdef')
                        except:
                            is_refdef = False

                        if is_refdef == True:
                            # Shapes don't need to have silkscreen
                            # reference designators
                            if component_type != 'shape':
                                refdef_group = et.SubElement(
                                    svg_layer, 'g', transform=transform)
                                refdef_group.set(
                                    '{' + config.cfg['ns']['pcbmode'] +
                                    '}type', 'refdef')
                                refdef_group.set(
                                    '{' + config.cfg['ns']['pcbmode'] +
                                    '}refdef', refdef)
                                placed_element = place.placeShape(
                                    shape, refdef_group, invert)
                        else:
                            placed_element = place.placeShape(
                                shape, shape_group, invert)

                # Assembly
                shapes = shapes_dict['assembly'].get(pcb_layer) or []
                try:
                    svg_layer = self._layers[pcb_layer]['assembly']['layer']
                except:
                    svg_layer = None

                if len(shapes) > 0 and svg_layer != None:
                    transform = "translate(%s,%s)" % (
                        location[0], config.cfg['invert-y'] * location[1])
                    group = et.SubElement(svg_layer, 'g', transform=transform)
                    for shape in shapes:
                        placed_element = place.placeShape(shape, group, invert)

                # Drills
                shapes = shapes_dict['drills'].get(pcb_layer) or []
                if len(shapes) > 0:
                    svg_layer = self._layers['drills']['layer']
                    transform = "translate(%s,%s)" % (
                        location[0], config.cfg['invert-y'] * location[1])
                    group = et.SubElement(svg_layer, 'g', transform=transform)
                    group.set('{' + config.cfg['ns']['pcbmode'] + '}type',
                              'component-shapes')
                    for shape in shapes:
                        placed_element = place.placeShape(shape, group, invert)
                        placed_element.set(
                            '{' + config.cfg['ns']['pcbmode'] + '}diameter',
                            str(shape.getDiameter()))

            # Place component origin marker
            svg_layer = self._layers[placement_layer]['placement']['layer']

            # Here pcb_layer may not exist for components that define
            # shapes for internal layers but only surface layers are
            # defined in the stackup
            try:
                group = et.SubElement(svg_layer, 'g', transform=transform)
            except:
                return

            group.set('{' + config.cfg['ns']['pcbmode'] + '}type',
                      component_type)
            group.set('{' + config.cfg['ns']['pcbmode'] + '}footprint',
                      component.getFootprintName())
            if (component_type == 'component') or (component_type == 'shape'):
                group.set('{' + config.cfg['ns']['pcbmode'] + '}refdef',
                          refdef)

            path = svg.placementMarkerPath()
            transform = "translate(%s,%s)" % (
                location[0], config.cfg['invert-y'] * location[1])

            if placement_layer == 'bottom':
                rotation *= -1

            marker_element = et.SubElement(group,
                                           'path',
                                           d=path,
                                           transform="rotate(%s)" % rotation)

            if (component_type == 'component'):
                style = utils.dictToStyleText(
                    config.stl['layout']['placement']['text'])

                t = et.SubElement(group, 'text', x="0", y="-0.17", style=style)
                ts = et.SubElement(t, 'tspan', x="0", dy="0.1")
                ts.text = "%s" % (refdef)
                ts = et.SubElement(t, 'tspan', x="0", dy="0.1")
                ts.text = htmlpar.unescape("%s°" % (rotation))
                ts = et.SubElement(t, 'tspan', x="0", dy="0.1")
                ts.text = "[%.2f,%.2f]" % (location[0], location[1])
            elif (component_type == 'shape'):
                style = utils.dictToStyleText(
                    config.stl['layout']['placement']['text'])

                t = et.SubElement(group, 'text', x="0", y="-0.17", style=style)
                ts = et.SubElement(t, 'tspan', x="0", dy="0.1")
                ts.text = "%s" % (refdef)
                ts = et.SubElement(t, 'tspan', x="0", dy="0.1")
                ts.text = htmlpar.unescape("%s°" % (rotation))
                ts = et.SubElement(t, 'tspan', x="0", dy="0.1")
                ts.text = "[%.2f,%.2f]" % (location[0], location[1])
            elif (component_type == 'via'):
                style = utils.dictToStyleText(
                    config.stl['layout']['placement']['text'])

                t = et.SubElement(group, 'text', x="0", y="-0.11", style=style)
                ts = et.SubElement(t, 'tspan', x="0", dy="0.1")
                ts.text = htmlpar.unescape("%s°" % (rotation))
                ts = et.SubElement(t, 'tspan', x="0", dy="0.1")
                ts.text = "[%.2f,%.2f]" % (location[0], location[1])
            else:
                continue
Пример #10
0
    def _placeComponents(self, components, component_type, print_refdef=False):
        """
        """
        for component in components:
            shapes_dict = component.getShapes()
            location = component.getLocation()

            # If the component is placed on the bottom layer we need
            # to invert the shapes AND their 'x' coordinate.  This is
            # sone using the 'invert' indicator set below
            refdef = component.getRefdef()

            if print_refdef == True:
                print refdef,

            placement_layer = component.getPlacementLayer()
            if placement_layer == 'bottom':
                invert = True
            else:
                invert = False

            for pcb_layer in utils.getSurfaceLayers():

                there_are_pours = utils.checkForPoursInLayer(pcb_layer)

                # Copper
                shapes = shapes_dict['copper'][pcb_layer]
                if len(shapes) > 0:
                    svg_layer = self._layers[pcb_layer]['copper']['pads']['layer']
     
                    transform = "translate(%s,%s)" % (location[0],
                                                      config.cfg['invert-y']*location[1])
                    group = et.SubElement(svg_layer, 'g', 
                                          transform=transform)

                    if component_type == 'components':
                        group.set('{'+config.cfg['ns']['pcbmode']+'}refdef', component.getRefdef())
                    elif component_type == 'vias':
                        group.set('{'+config.cfg['ns']['pcbmode']+'}type', 'via')
                        group.set('{'+config.cfg['ns']['pcbmode']+'}via', component.getFootprintName())
                    else:
                        pass

                    for shape in shapes:
                        place.placeShape(shape, group)
                        if there_are_pours == True:
                            mask_group = et.SubElement(self._masks[pcb_layer], 'g', 
                                                       transform=transform)
                            self._placeMask(mask_group, 
                                            shape,
                                            'pad')

                    # Add pin labels
                    labels = shapes_dict['pin-labels'][pcb_layer]
                    if labels != []:
                        style = utils.dictToStyleText(config.stl['layout']['board']['pad-labels'])
                        label_group = et.SubElement(group, 'g', 
                                                    transform="rotate(%s)" % component.getRotation(),
                                                    style=style)
                        for label in labels:
                            t = et.SubElement(label_group, 'text',
                                              x=str(label['location'][0]),
                                              # TODO: get rid of this hack
                                              y=str(-label['location'][1]))
                                              #y=str(-pin_location.y + pad_numbers_font_size/3),
                                              #refdef=self._refdef)
                            t.text = label['text']





                # Soldermask
                shapes = shapes_dict['soldermask'][pcb_layer]
                if len(shapes) > 0:
                    svg_layer = self._layers[pcb_layer]['soldermask']['layer']
                    transform = "translate(%s,%s)" % (location[0],
                                                      config.cfg['invert-y']*location[1])
                    group = et.SubElement(svg_layer, 'g', transform=transform)
                    group.set('{'+config.cfg['ns']['pcbmode']+'}type', 'component-shapes')
                    for shape in shapes:
                        placed_element = place.placeShape(shape, group)
     
                    # Solderpaste
                    shapes = shapes_dict['solderpaste'][pcb_layer]
                    svg_layer = self._layers[pcb_layer]['solderpaste']['layer']
                    transform = "translate(%s,%s)" % (location[0],
                                                      config.cfg['invert-y']*location[1])
                    group = et.SubElement(svg_layer, 'g', transform=transform)
                    group.set('{'+config.cfg['ns']['pcbmode']+'}type', 'component-shapes')
                    for shape in shapes:
                        placed_element = place.placeShape(shape, group, invert)


                # Silkscreen
                shapes = shapes_dict['silkscreen'][pcb_layer]
                if len(shapes) > 0:
                    svg_layer = self._layers[pcb_layer]['silkscreen']['layer']
                    transform = "translate(%s,%s)" % (location[0],
                                                      config.cfg['invert-y']*location[1])
                    shape_group = et.SubElement(svg_layer, 'g', transform=transform)
                    shape_group.set('{'+config.cfg['ns']['pcbmode']+'}type', 'component-shapes')
     
                    for shape in shapes:
                        # Refdefs need to be in their own groups so that their
                        # location can later be extracted, hence this...
                        try:
                            is_refdef = getattr(shape, 'is_refdef')
                        except:
                            is_refdef = False

                        if is_refdef == True:
                            refdef_group = et.SubElement(svg_layer, 'g', transform=transform)
                            refdef_group.set('{'+config.cfg['ns']['pcbmode']+'}type', 'refdef')
                            refdef_group.set('{'+config.cfg['ns']['pcbmode']+'}refdef', refdef)
                            placed_element = place.placeShape(shape, refdef_group)
                        else:
                            placed_element = place.placeShape(shape, shape_group)


                # Assembly
                shapes = shapes_dict['assembly'][pcb_layer]
                if len(shapes) > 0: 
                    svg_layer = self._layers[pcb_layer]['assembly']['layer']
                    transform = "translate(%s,%s)" % (location[0],
                                                      config.cfg['invert-y']*location[1])
                    group = et.SubElement(svg_layer, 'g', transform=transform)
                    for shape in shapes:
                        placed_element = place.placeShape(shape, group)

                # Drills
                shapes = shapes_dict['drills'][pcb_layer]
                if len(shapes) > 0:
                    svg_layer = self._layers['drills']['layer']
                    transform = "translate(%s,%s)" % (location[0],
                                                      config.cfg['invert-y']*location[1])
                    group = et.SubElement(svg_layer, 'g', transform=transform)
                    group.set('{'+config.cfg['ns']['pcbmode']+'}type', 'component-shapes')
                    for shape in shapes:
                        placed_element = place.placeShape(shape, group)
                        placed_element.set('{'+config.cfg['ns']['pcbmode']+'}diameter',
                                           str(shape.getDiameter()))