예제 #1
0
    def check(self) -> bool:
        """
        Proceeds the checking of the rule.
        The following variables will be accessible after checking:
            * center_rect_polyline
        """

        # no checks for power-symbols, graphical symbols or derived symbols
        if (self.component.is_power_symbol()
                or self.component.is_graphic_symbol()
                or self.component.extends is not None):
            return False

        # check if component has just one rectangle, if not, skip checking
        self.center_rect_polyline = self.component.get_center_rectangle(
            range(self.component.unit_count))
        if self.center_rect_polyline is None:
            return False

        rectangle_need_fix = False
        if self.component.is_small_component_heuristics():
            if not math.isclose(self.center_rect_polyline.stroke_width,
                                mil_to_mm(10)):
                self.warning(
                    "Component outline is thickness {0}mil, recommended is {1}mil for"
                    " standard symbol".format(
                        mm_to_mil(self.center_rect_polyline.stroke_width), 10))
                self.warningExtra(
                    "exceptions are allowed for small symbols like resistor,"
                    " transistor, ...")
                rectangle_need_fix = False
        else:
            if not math.isclose(self.center_rect_polyline.stroke_width,
                                mil_to_mm(10)):
                self.error(
                    "Component outline is thickness {0}mil, recommended is {1}mil"
                    .format(mm_to_mil(self.center_rect_polyline.stroke_width),
                            10))
                rectangle_need_fix = True

        if self.center_rect_polyline.fill_type != "background":
            msg = (
                "Component background is filled with {0} color, recommended is filling"
                " with {1} color".format(self.center_rect_polyline.fill_type,
                                         "background"))
            if self.component.is_small_component_heuristics():
                self.warning(msg)
                self.warningExtra(
                    "exceptions are allowed for small symbols like resistor,"
                    " transistor, ...")
            else:
                self.error(msg)
                rectangle_need_fix = True

        return rectangle_need_fix
예제 #2
0
    def fix(self) -> None:
        """
        Proceeds the fixing of the rule, if possible.
        """
        if self.violating_properties:
            self.info("Fixing field text size")
        for prop in self.violating_properties:
            prop.effects.sizex = mil_to_mm(50)
            prop.effects.sizey = mil_to_mm(50)

        if self.violating_pins:
            self.info("Fixing pin text size")
        for pin in self.violating_pins:
            pin.name_effect.sizex = mil_to_mm(50)
            pin.name_effect.sizey = mil_to_mm(50)
            pin.number_effect.sizex = mil_to_mm(50)
            pin.number_effect.sizey = mil_to_mm(50)
        self.recheck()
    def appendToSymbol(self, symbol):
        """
        Convert the drawing elements to equivalent objects and append them to a KicadSymbol object
        """

        for r in self.rectangle:
            rect = kicad_sym.Rectangle.new_mil(r.start.x, r.start.y, r.end.x,
                                               r.end.y)
            rect.stroke_width = kicad_sym.mil_to_mm(r.line_width)
            rect.fill_type = r.fill
            rect.unit = r.unit_idx
            rect.demorgan = r.deMorgan_idx
            symbol.rectangles.append(rect)

        for p in self.pins:
            pin = kicad_sym.Pin(
                p.name, str(p.num), str(p.el_type),
                kicad_sym.mil_to_mm(p.at.x), kicad_sym.mil_to_mm(p.at.y),
                kicad_sym.Pin.dir_to_rotation(str(p.orientation)),
                str(p.style), kicad_sym.mil_to_mm(p.pin_length))
            pin.is_hidden = p.visibility == DrawingPin.PinVisibility.INVISIBLE
            pin.name_effect.sizex = kicad_sym.mil_to_mm(p.fontsize_pinname)
            pin.name_effect.sizey = pin.name_effect.sizex
            pin.number_effect.sizex = kicad_sym.mil_to_mm(p.fontsize_pinnumber)
            pin.number_effect.sizey = pin.number_effect.sizex
            pin.unit = p.unit_idx
            pin.demorgan = p.deMorgan_idx
            symbol.pins.append(pin)

        for a in self.arc:
            start = Point(distance=a.radius,
                          angle=a.angle_start / 10).translate(a.at)
            end = Point(distance=a.radius,
                        angle=a.angle_end / 10).translate(a.at)

            arc = kicad_sym.Arc(kicad_sym.mil_to_mm(start.x),
                                kicad_sym.mil_to_mm(start.y),
                                kicad_sym.mil_to_mm(end.x),
                                kicad_sym.mil_to_mm(end.y),
                                kicad_sym.mil_to_mm(a.at.x),
                                kicad_sym.mil_to_mm(a.at.y),
                                kicad_sym.mil_to_mm(a.radius),
                                a.angle_start / 10, a.angle_end / 10)

            arc.stroke_width = kicad_sym.mil_to_mm(a.line_width)
            arc.fill_type = a.fill
            arc.unit = a.unit_idx
            arc.demorgan = a.deMorgan_idx
            symbol.arcs.append(arc)

        for c in self.circle:
            circle = kicad_sym.Circle(kicad_sym.mil_to_mm(c.at.x),
                                      kicad_sym.mil_to_mm(c.at.y),
                                      kicad_sym.mil_to_mm(c.radius),
                                      kicad_sym.mil_to_mm(c.line_width))
            circle.fill_type = c.fill
            circle.unit = c.unit_idx
            circle.demorgan = c.deMorgan_idx
            symbol.circles.append(circle)

        for t in self.text:
            text = kicad_sym.Text(
                t.text, kicad_sym.mil_to_mm(t.at.x),
                kicad_sym.mil_to_mm(t.at.y), t.angle,
                kicad_sym.TextEffect(kicad_sym.mil_to_mm(t.size),
                                     kicad_sym.mil_to_mm(t.size)))
            text.effects.is_italic = t.font_type == DrawingText.FontType.ITALIC
            text.effects.is_bold = t.font_weight == DrawingText.FontWeight.BOLD
            text.effects.is_hidden = t.hidden == 1
            if t.halign == DrawingText.HorizontalAlignment.CENTER:
                text.effects.h_justify = "center"
            elif t.halign == DrawingText.HorizontalAlignment.LEFT:
                text.effects.h_justify = "left"
            if t.halign == DrawingText.HorizontalAlignment.RIGHT:
                text.effects.h_justify = "right"
            if t.valign == DrawingText.VerticalAlignment.CENTER:
                text.effects.v_justify = "center"
            elif t.valign == DrawingText.VerticalAlignment.TOP:
                text.effects.v_justify = "top"
            elif t.valign == DrawingText.VerticalAlignment.BOTTOM:
                text.effects.v_justify = "bottom"
            text.unit = t.unit_idx
            text.demorgan = t.deMorgan_idx
            symbol.texts.append(text)

        for p in self.polyline:
            pts = []
            for pt in p.points:
                pts.append(kicad_sym.Point.new_mil(pt.x, pt.y))

            poly = kicad_sym.Polyline(pts)
            poly.unit = p.unit_idx
            poly.demorgan = p.deMorgan_idx
            poly.stroke_width = kicad_sym.mil_to_mm(p.line_width)
            poly.fill_type = p.fill
            symbol.polylines.append(poly)

        symbol.unit_count = 1
        symbol.demorgan_count = 1
예제 #4
0
    def check(self) -> bool:
        """
        Proceeds the checking of the rule.
        The following variables will be accessible after checking:
            * recommended_ref_pos
            * recommended_ref_alignment
            * recommended_name_pos
            * recommended_name_alignment
            * recommended_fp_pos
            * recommended_fp_alignment
        """

        # check if component has just one rectangle, if not, skip checking
        ctr = self.component.get_center_rectangle(units=[0, 1])
        if not ctr:
            return False

        (maxx, top, minx, bottom) = ctr.get_boundingbox()

        # reference checking

        # If there is no pin in the top, the recommended position to ref is at top-center,
        # horizontally centered.
        if not self.component.filter_pins(direction="D"):
            self.recommended_ref_pos = {
                "posx": 0,
                "posy": (top + mil_to_mm(125))
            }
            self.recommended_ref_alignment = "center"

        # otherwise, the recommended is put it before the first pin x position, right-aligned
        else:
            x = min([
                i.posx for i in self.component.filter_pins(direction="D")
            ]) - mil_to_mm(100)
            self.recommended_ref_pos = {
                "posx": x,
                "posy": (top + mil_to_mm(125))
            }
            self.recommended_ref_alignment = "right"

        # get the current reference infos and compare them to recommended ones
        ref = self.component.get_property("Reference")
        if ref:
            if not ref.compare_pos(self.recommended_ref_pos["posx"],
                                   self.recommended_ref_pos["posy"]):
                self.warning("field: reference, {0}, recommended {1}".format(
                    positionFormater(ref),
                    positionFormater(self.recommended_ref_pos),
                ))
            if ref.effects.h_justify != self.recommended_ref_alignment:
                self.warning(
                    "field: reference, justification {0}, recommended {1}".
                    format(ref.effects.h_justify,
                           self.recommended_ref_alignment))
            # Does vertical alignment matter too?
            # What about orientation checking?

        # name checking

        # If there is no pin in the top, the recommended position to name is at top-center,
        # horizontally centered.
        if not self.component.filter_pins(direction="D"):
            self.recommended_name_pos = {
                "posx": 0,
                "posy": (top + mil_to_mm(50))
            }
            self.recommended_name_alignment = "center"

        # otherwise, the recommended is put it before the first pin x position, right-aligned
        else:
            x = min([
                i.posx for i in self.component.filter_pins(direction="D")
            ]) - mil_to_mm(100)
            self.recommended_name_pos = {
                "posx": x,
                "posy": (top + mil_to_mm(50))
            }
            self.recommended_name_alignment = "right"

        # get the current name infos and compare them to recommended ones
        name = self.component.get_property("Value")
        if name:
            if not name.compare_pos(self.recommended_name_pos["posx"],
                                    self.recommended_name_pos["posy"]):
                self.warning("field: name, {0}, recommended {1}".format(
                    positionFormater(name),
                    positionFormater(self.recommended_name_pos),
                ))
            if name.effects.h_justify != self.recommended_name_alignment:
                self.warning(
                    "field: name, justification {0}, recommended {1}".format(
                        name.effects.h_justify,
                        self.recommended_name_alignment))

        # footprint checking

        # If there is no pin in the bottom, the recommended position to footprint is at
        # bottom-center, horizontally centered.
        if not self.component.filter_pins(direction="U"):
            self.recommended_fp_pos = {
                "posx": 0,
                "posy": (bottom - mil_to_mm(50))
            }
            self.recommended_fp_alignment = "center"

        # otherwise, the recommended is put it after the last pin x position, left-aligned
        else:
            x = max([
                i.posx for i in self.component.filter_pins(direction="U")
            ]) + mil_to_mm(50)
            self.recommended_fp_pos = {
                "posx": x,
                "posy": (bottom - mil_to_mm(50))
            }
            self.recommended_fp_alignment = "left"

        # get the current footprint infos and compare them to recommended ones
        fp = self.component.get_property("Footprint")
        if fp:
            if not fp.compare_pos(self.recommended_fp_pos["posx"],
                                  self.recommended_fp_pos["posy"]):
                self.warning("field: footprint, {0}, recommended {1}".format(
                    positionFormater(fp),
                    positionFormater(self.recommended_fp_pos)))
            if fp.effects.h_justify != self.recommended_fp_alignment:
                self.warning(
                    "field: footprint, justification {0}, recommended {1}".
                    format(fp.effects.h_justify,
                           self.recommended_fp_alignment))

        # This entire rule only generates a WARNING (won't fail a component, only display a
        # message).
        return False
예제 #5
0
def generateSIPResistorPack(count):
    name = "R_Pack{:02d}_SIP".format(count)
    refdes = "RN"
    footprint = "Resistor_THT:R_Array_SIP{0}".format(count * 2)
    footprint_filter = "R?Array?SIP*"
    description = "{0} resistor network, parallel topology, SIP package".format(count)
    keywords = "R network parallel topology isolated"
    datasheet = "http://www.vishay.com/docs/31509/csc.pdf"

    grid_size = 100
    resistor_horizontal_spacing = 300
    pin_length = 150
    resistor_length = 160
    resistor_width = 60
    resistor_long_lead_length = 30
    body_left_offset = 50
    left = -roundToGrid(((count - 1) * resistor_horizontal_spacing) / 2, 100)
    body_x = left - body_left_offset
    body_y = -75
    body_height = 250
    body_width = (
        (count - 1) * resistor_horizontal_spacing + grid_size
    ) + 2 * body_left_offset
    bottom = 200

    symbol = KicadSymbol.new(
        name,
        libname,
        refdes,
        footprint,
        datasheet,
        keywords,
        description,
        footprint_filter,
    )
    library.symbols.append(symbol)

    symbol.hide_pin_names = True
    symbol.pin_names_offset = 0
    symbol.get_property("Reference").set_pos_mil(body_x - 50, 0, 90)
    symbol.get_property("Value").set_pos_mil(body_x + body_width + 50, 0, 90)
    symbol.get_property("Footprint").set_pos_mil(body_x + body_width + 50 + 75, 0, 90)

    # Symbol body
    symbol.rectangles.append(
        Rectangle.new_mil(body_x, body_y, body_x + body_width, body_y + body_height)
    )

    pin_left = left

    for s in range(1, count + 1):
        # Resistor short pins
        symbol.pins.append(
            Pin(
                name="R{0}.1".format(s),
                number=str(2 * s - 1),
                etype="passive",
                posx=mil_to_mm(pin_left),
                posy=mil_to_mm(-bottom),
                rotation=90,
                length=mil_to_mm(pin_length),
            )
        )
        # Resistor long pins
        symbol.pins.append(
            Pin(
                name="R{0}.2".format(s),
                number=str(2 * s),
                etype="passive",
                posx=mil_to_mm(pin_left + grid_size),
                posy=mil_to_mm(-bottom),
                rotation=90,
                length=mil_to_mm(pin_length),
            )
        )
        # Resistor bodies
        symbol.rectangles.append(
            Rectangle.new_mil(
                pin_left + resistor_width / 2,
                -(bottom - pin_length),
                pin_left - resistor_width / 2,
                -(bottom - pin_length - resistor_length),
            )
        )
        # Resistor long leads
        symbol.polylines.append(
            Polyline(
                points=[
                    Point.new_mil(pin_left, -(bottom - pin_length - resistor_length)),
                    Point.new_mil(
                        pin_left,
                        -(
                            bottom
                            - pin_length
                            - resistor_length
                            - resistor_long_lead_length
                        ),
                    ),
                    Point.new_mil(
                        pin_left + grid_size,
                        -(
                            bottom
                            - pin_length
                            - resistor_length
                            - resistor_long_lead_length
                        ),
                    ),
                    Point.new_mil(pin_left + grid_size, -(bottom - pin_length)),
                ],
                stroke_width=0,
            )
        )

        pin_left = pin_left + resistor_horizontal_spacing
예제 #6
0
def generateResistorPack(count):
    name = "R_Pack{:02d}".format(count)
    refdes = "RN"
    footprint = ""
    footprint_filter = ["DIP*", "SOIC*"]
    description = "{0} resistor network, parallel topology, DIP package".format(count)
    keywords = "R network parallel topology isolated"
    datasheet = "~"

    grid_size = 100
    pin_length = 100
    resistor_length = 150
    resistor_width = 50
    body_left_offset = 50
    body_top_offset = 20
    left = -roundToGrid(((count - 1) * grid_size) / 2, 100)
    body_x = left - body_left_offset
    body_height = resistor_length + 2 * body_top_offset
    body_y = -body_height / 2
    body_width = ((count - 1) * grid_size) + 2 * body_left_offset
    top = -200
    bottom = 200

    symbol = KicadSymbol.new(
        name,
        libname,
        refdes,
        footprint,
        datasheet,
        keywords,
        description,
        footprint_filter,
    )
    library.symbols.append(symbol)

    symbol.hide_pin_names = True
    symbol.pin_names_offset = 0
    symbol.get_property("Reference").set_pos_mil(body_x - 50, 0, 90)
    symbol.get_property("Value").set_pos_mil(body_x + body_width + 50, 0, 90)
    symbol.get_property("Footprint").set_pos_mil(body_x + body_width + 50 + 75, 0, 90)

    # Symbol body
    symbol.rectangles.append(
        Rectangle.new_mil(body_x, body_y, body_x + body_width, body_y + body_height)
    )

    pin_left = left

    for s in range(1, count + 1):
        # Resistor bottom pins
        symbol.pins.append(
            Pin(
                name="R{0}.1".format(s),
                number=str(s),
                etype="passive",
                posx=mil_to_mm(pin_left),
                posy=mil_to_mm(-bottom),
                rotation=90,
                length=mil_to_mm(pin_length),
            )
        )
        # Resistor top pins
        symbol.pins.append(
            Pin(
                name="R{0}.2".format(s),
                number=str(2 * count - s + 1),
                etype="passive",
                posx=mil_to_mm(pin_left),
                posy=mil_to_mm(-top),
                rotation=270,
                length=mil_to_mm(pin_length),
            )
        )
        # Resistor bodies
        symbol.rectangles.append(
            Rectangle.new_mil(
                pin_left + resistor_width / 2,
                -(resistor_length / 2),
                pin_left - resistor_width / 2,
                -(-resistor_length / 2),
            )
        )
        # Resistor bottom leads
        symbol.polylines.append(
            Polyline(
                points=[
                    Point.new_mil(pin_left, -(bottom - pin_length)),
                    Point.new_mil(pin_left, -(resistor_length / 2)),
                ],
                stroke_width=0,
            )
        )
        # Resistor top leads
        symbol.polylines.append(
            Polyline(
                [
                    Point.new_mil(pin_left, -(-resistor_length / 2)),
                    Point.new_mil(pin_left, -(top + pin_length)),
                ],
                stroke_width=0,
            )
        )

        pin_left = pin_left + grid_size
예제 #7
0
def generateResistorNetwork(count):
    name = "R_Network{:02d}".format(count)
    refdes = "RN"
    footprint = "Resistor_THT:R_Array_SIP{0}".format(count + 1)
    footprint_filter = "R?Array?SIP*"
    description = (
        "{0} resistor network, star topology, bussed resistors, small symbol".format(
            count
        )
    )
    keywords = "R network star-topology"
    datasheet = "http://www.vishay.com/docs/31509/csc.pdf"

    grid_size = 100
    junction_diameter = 20
    pin_length = 100
    resistor_length = 160
    resistor_width = 60
    resistor_top_lead_length = 30
    body_left_offset = 50
    left = -math.floor(count / 2) * grid_size
    body_x = left - body_left_offset
    body_y = -125
    body_height = 250
    body_width = (count - 1) * grid_size + 2 * body_left_offset
    top = -200
    bottom = 200

    symbol = KicadSymbol.new(
        name,
        libname,
        refdes,
        footprint,
        datasheet,
        keywords,
        description,
        footprint_filter,
    )
    library.symbols.append(symbol)

    symbol.hide_pin_names = True
    symbol.pin_names_offset = 0
    symbol.get_property("Reference").set_pos_mil(body_x - 50, 0, 90)
    symbol.get_property("Value").set_pos_mil(body_x + body_width + 50, 0, 90)
    symbol.get_property("Footprint").set_pos_mil(body_x + body_width + 50 + 75, 0, 90)

    # Symbol body
    symbol.rectangles.append(
        Rectangle.new_mil(body_x, body_y, body_x + body_width, body_y + body_height)
    )

    pin_left = left

    # Common pin
    symbol.pins.append(
        Pin(
            "common",
            str(1),
            "passive",
            mil_to_mm(pin_left),
            mil_to_mm(-top),
            rotation=270,
        )
    )

    # First top resistor lead
    symbol.polylines.append(
        Polyline(
            points=[
                Point.new_mil(pin_left, -(top + pin_length)),
                Point.new_mil(pin_left, -(bottom - pin_length - resistor_length)),
            ]
        )
    )

    # print(symbol.properties)

    for s in range(1, count + 1):
        # Resistor pins
        symbol.pins.append(
            Pin(
                name="R{0}".format(s),
                number=str(s + 1),
                etype="passive",
                posx=mil_to_mm(pin_left),
                posy=mil_to_mm(top),
                rotation=90,
                length=mil_to_mm(pin_length),
            )
        )
        # Resistor bodies
        symbol.rectangles.append(
            Rectangle.new_mil(
                pin_left + resistor_width / 2,
                -(bottom - pin_length),
                pin_left - resistor_width / 2,
                -(bottom - pin_length - resistor_length),
            )
        )

        if s < count:
            # Top resistor leads
            symbol.polylines.append(
                Polyline(
                    points=[
                        Point.new_mil(
                            pin_left, -(bottom - pin_length - resistor_length)
                        ),
                        Point.new_mil(
                            pin_left,
                            -(
                                bottom
                                - pin_length
                                - resistor_length
                                - resistor_top_lead_length
                            ),
                        ),
                        Point.new_mil(
                            pin_left + grid_size,
                            -(
                                bottom
                                - pin_length
                                - resistor_length
                                - resistor_top_lead_length
                            ),
                        ),
                        Point.new_mil(
                            pin_left + grid_size,
                            -(bottom - pin_length - resistor_length),
                        ),
                    ],
                    stroke_width=0,
                )
            )
            # Junctions
            symbol.circles.append(
                Circle(
                    centerx=mil_to_mm(pin_left),
                    centery=mil_to_mm(
                        -(
                            bottom
                            - pin_length
                            - resistor_length
                            - resistor_top_lead_length
                        )
                    ),
                    radius=mil_to_mm(junction_diameter / 2),
                    fill_type="outline",
                    stroke_width=0,
                )
            )

        pin_left = pin_left + grid_size
예제 #8
0
def generateSIPNetworkDividers(count):
    name = "R_Network_Dividers_x{:02d}_SIP".format(count)
    refdes = "RN"
    footprint = "Resistor_THT:R_Array_SIP{0}".format(count + 2)
    footprint_filter = "R?Array?SIP*"
    description = "{0} voltage divider network, dual terminator, SIP package".format(
        count
    )
    keywords = "R network divider topology"
    datasheet = "http://www.vishay.com/docs/31509/csc.pdf"

    grid_size = 200
    junction_diameter = 20
    pin_length = 100
    resistor_length = 100
    resistor_width = 40
    body_left_offset = 50
    left = -math.floor(count / 2) * grid_size
    top = -300
    bottom = 300
    body_x = left - body_left_offset
    body_y = top + pin_length
    body_height = abs(bottom - pin_length - body_y)
    body_width = (count - 1) * grid_size + grid_size / 2 + 2 * body_left_offset
    resistor_vertical_spacing = (body_height - 2 * resistor_length) / 3

    symbol = KicadSymbol.new(
        name,
        libname,
        refdes,
        footprint,
        datasheet,
        keywords,
        description,
        footprint_filter,
    )
    library.symbols.append(symbol)

    symbol.hide_pin_names = True
    symbol.pin_names_offset = 0
    symbol.get_property("Reference").set_pos_mil(body_x - 50, 0, 90)
    symbol.get_property("Value").set_pos_mil(body_x + body_width + 50, 0, 90)
    symbol.get_property("Footprint").set_pos_mil(body_x + body_width + 50 + 75, 0, 90)

    # Symbol body
    symbol.rectangles.append(
        Rectangle.new_mil(body_x, body_y, body_x + body_width, body_y + body_height)
    )

    pin_left = left

    # Common 1 pin
    symbol.pins.append(
        Pin(
            "COM1",
            str(1),
            "passive",
            mil_to_mm(pin_left),
            mil_to_mm(-top),
            rotation=270,
            length=mil_to_mm(pin_length),
        )
    )
    # Common 2 pin
    symbol.pins.append(
        Pin(
            "COM2",
            str(count + 2),
            "passive",
            mil_to_mm(left + (count - 1) * grid_size + grid_size / 2),
            mil_to_mm(-top),
            rotation=270,
            length=mil_to_mm(pin_length),
        )
    )

    # Vertical COM2 lead
    symbol.polylines.append(
        Polyline(
            points=[
                Point.new_mil(
                    left + (count - 1) * grid_size + grid_size / 2,
                    -(bottom - pin_length - resistor_vertical_spacing / 2),
                ),
                Point.new_mil(
                    left + (count - 1) * grid_size + grid_size / 2, -(top + pin_length)
                ),
            ],
            stroke_width=0,
        )
    )

    for s in range(1, count + 1):
        # Voltage divider center pins
        symbol.pins.append(
            Pin(
                name="R{0}".format(s),
                number=str(s + 1),
                etype="passive",
                posx=mil_to_mm(pin_left),
                posy=mil_to_mm(-bottom),
                rotation=90,
                length=mil_to_mm(pin_length),
            )
        )
        # Top resistor bodies
        symbol.rectangles.append(
            Rectangle.new_mil(
                pin_left + resistor_width / 2,
                -(top + pin_length + resistor_vertical_spacing + resistor_length),
                pin_left - resistor_width / 2,
                -(top + pin_length + resistor_vertical_spacing),
            )
        )
        # Bottom resistor bodies
        symbol.rectangles.append(
            Rectangle.new_mil(
                pin_left + 3 * resistor_width / 2 + resistor_width / 2,
                -(bottom - pin_length - resistor_vertical_spacing - resistor_length),
                pin_left + 3 * resistor_width / 2 - resistor_width / 2,
                -(bottom - pin_length - resistor_vertical_spacing),
            )
        )
        # Horizontal COM2 leads
        symbol.polylines.append(
            Polyline(
                points=[
                    Point.new_mil(
                        pin_left + 3 * resistor_width / 2,
                        -(bottom - pin_length - resistor_vertical_spacing),
                    ),
                    Point.new_mil(
                        pin_left + 3 * resistor_width / 2,
                        -(bottom - pin_length - resistor_vertical_spacing / 2),
                    ),
                    Point.new_mil(
                        left + (count - 1) * grid_size + grid_size / 2,
                        -(bottom - pin_length - resistor_vertical_spacing / 2),
                    ),
                ],
                stroke_width=0,
            )
        )

        if s == 1:
            # First resistor top lead
            symbol.polylines.append(
                Polyline(
                    points=[
                        Point.new_mil(pin_left, -(top + pin_length)),
                        Point.new_mil(
                            pin_left, -(top + pin_length + resistor_vertical_spacing)
                        ),
                    ],
                    stroke_width=0,
                )
            )

        if s > 1:
            # Top resistor top leads
            symbol.polylines.append(
                Polyline(
                    points=[
                        Point.new_mil(
                            pin_left - grid_size,
                            -(top + pin_length + resistor_vertical_spacing / 2),
                        ),
                        Point.new_mil(
                            pin_left,
                            -(top + pin_length + resistor_vertical_spacing / 2),
                        ),
                        Point.new_mil(
                            pin_left, -(top + pin_length + resistor_vertical_spacing)
                        ),
                    ],
                    stroke_width=0,
                )
            )

        # Top resistor bottom leads
        symbol.polylines.append(
            Polyline(
                points=[
                    Point.new_mil(pin_left, -(bottom - pin_length)),
                    Point.new_mil(
                        pin_left,
                        -(
                            top
                            + pin_length
                            + resistor_vertical_spacing
                            + resistor_length
                        ),
                    ),
                ],
                stroke_width=0,
            )
        )
        # Bottom resistor top leads
        symbol.polylines.append(
            Polyline(
                points=[
                    Point.new_mil(
                        pin_left,
                        -(
                            top
                            + pin_length
                            + resistor_vertical_spacing
                            + resistor_length
                            + resistor_vertical_spacing / 2
                        ),
                    ),
                    Point.new_mil(
                        pin_left + 3 * resistor_width / 2,
                        -(
                            top
                            + pin_length
                            + resistor_vertical_spacing
                            + resistor_length
                            + resistor_vertical_spacing / 2
                        ),
                    ),
                    Point.new_mil(
                        pin_left + 3 * resistor_width / 2,
                        -(
                            bottom
                            - pin_length
                            - resistor_vertical_spacing
                            - resistor_length
                        ),
                    ),
                ],
                stroke_width=0,
            )
        )
        # Center junctions
        symbol.circles.append(
            Circle(
                centerx=mil_to_mm(pin_left),
                centery=mil_to_mm(0),
                radius=mil_to_mm(junction_diameter / 2),
                fill_type="outline",
                stroke_width=0,
            )
        )

        if s > 1:
            # Bottom junctions
            symbol.circles.append(
                Circle(
                    centerx=mil_to_mm(pin_left + 3 * resistor_width / 2),
                    centery=mil_to_mm(
                        -(bottom - pin_length - resistor_vertical_spacing / 2)
                    ),
                    radius=mil_to_mm(junction_diameter / 2),
                    fill_type="outline",
                    stroke_width=0,
                )
            )

        if s < count:
            # Top junctions
            symbol.circles.append(
                Circle(
                    centerx=mil_to_mm(pin_left),
                    centery=mil_to_mm(
                        -(top + pin_length + resistor_vertical_spacing / 2)
                    ),
                    radius=mil_to_mm(junction_diameter / 2),
                    fill_type="outline",
                    stroke_width=0,
                )
            )

        pin_left = pin_left + grid_size
예제 #9
0
def generateSingleSymbol(library, series_params, num_pins_per_row, lib_params):
    pincount = series_params.num_rows * num_pins_per_row + (
        1 if series_params.odd_count else 0)
    symbol_name = series_params.symbol_name_format.format(
        num_pins_per_row=num_pins_per_row,
        suffix=lib_params.get('suffix', ""),
        num_pins=pincount)

    fp_filter = [
        filter.format(pn_modifier=lib_params.get("pn_modifier", ''))
        for filter in series_params.footprint_filter
    ]

    libname = os.path.basename(library.filename)
    libname = os.path.splitext(libname)[0]

    current_symbol = kicad_sym.KicadSymbol.new(
        symbol_name, libname, reference_designator, '',
        series_params.datasheet, series_params.keywords,
        series_params.description.format(num_pins_per_row=num_pins_per_row,
                                         num_pins=pincount,
                                         extra_pin=lib_params.get(
                                             'extra_pin_descr', '')) +
        ', script generated (kicad-library-utils/symbol-generators/connector/)',
        fp_filter)
    library.symbols.append(current_symbol)

    current_symbol.hide_pin_names = True
    current_symbol.pin_names_offset = kicad_sym.mil_to_mm(40)

    ########################## reference points ################################
    num_pins_left_side = num_pins_per_row + (1
                                             if series_params.odd_count else 0)

    top_left_pin_position = Point(
        {
            'x': -pin_length - body_width_per_row,
            'y': pin_spacing_y * (num_pins_left_side - 1) / 2.0
        },
        grid=pin_grid)

    if series_params.num_rows == 2:
        top_right_pin_position = top_left_pin_position.translate(
            {
                'x': 2 * pin_length + 2 * body_width_per_row,
                'y': 0
            },
            apply_on_copy=True)

    body_top_left_corner = top_left_pin_position.translate(
        {
            'x': pin_length,
            'y': pin_spacing_y / 2
        },
        apply_on_copy=True,
        new_grid=None)

    body_width = pin_spacing_y * series_params.num_rows
    body_bottom_right_corner = body_top_left_corner.translate(
        {
            'x': body_width,
            'y': -pin_spacing_y * num_pins_left_side
        },
        apply_on_copy=True)

    extra_pin = lib_params.get('extra_pin')

    if extra_pin:
        extra_pin_pos = body_bottom_right_corner.translate(
            {
                'x': -body_width / 2,
                'y': -pin_length
            },
            apply_on_copy=True,
            new_grid=extra_pin_grid)
        extra_pin_length = body_bottom_right_corner.y - extra_pin_pos.y - extra_pin[
            'offset']

    if extra_pin == SHIELD_PIN:
        shield_top_left_corner = body_top_left_corner
        shield_bottom_right_corner = body_bottom_right_corner

        body_top_left_corner = shield_top_left_corner.translate(
            {
                'x': 10,
                'y': -10
            }, apply_on_copy=True, new_grid=None)
        body_bottom_right_corner = shield_bottom_right_corner.translate(
            {
                'x': -10,
                'y': 10
            }, apply_on_copy=True, new_grid=None)

    ############################ symbol fields #################################
    ref_pos = body_top_left_corner.translate(
        {
            'x': body_width / 2,
            'y': ref_fontsize
        }, apply_on_copy=True)

    reference = current_symbol.get_property('Reference')
    reference.set_pos_mil(ref_pos.x, ref_pos.y, 0)
    reference.effects.sizex = kicad_sym.mil_to_mm(ref_fontsize)
    reference.effects.sizey = reference.effects.sizex

    value_pos = body_bottom_right_corner.translate(
        {
            'x': -body_width / 2 + (50 if extra_pin else 0),
            'y': -ref_fontsize
        },
        apply_on_copy=True)

    value = current_symbol.get_property('Value')
    value.set_pos_mil(value_pos.x, value_pos.y, 0)
    value.effects.sizex = kicad_sym.mil_to_mm(ref_fontsize)
    value.effects.sizey = value.effects.sizex
    value.effects.v_justify = "left" if extra_pin else "center"

    ############################ artwork #################################
    drawing = Drawing()

    if series_params.enclosing_rectangle:
        drawing.append(
            DrawingRectangle(start=body_top_left_corner,
                             end=body_bottom_right_corner,
                             line_width=body_outline_line_width,
                             fill=body_fill))

    if extra_pin == SHIELD_PIN:
        drawing.append(
            DrawingRectangle(start=shield_top_left_corner,
                             end=shield_bottom_right_corner,
                             line_width=inner_graphics_line_width,
                             fill=ElementFill.NO_FILL))

    if extra_pin:
        drawing.append(
            DrawingPin(at=extra_pin_pos,
                       number=extra_pin['number'],
                       name=extra_pin['name'],
                       pin_length=extra_pin_length,
                       orientation=DrawingPin.PinOrientation.UP))
        if extra_pin['deco']:
            drawing.append(extra_pin['deco'](extra_pin_pos, extra_pin_length))

    repeated_drawing = [innerArtwork(series_params.graphic_type)]

    if series_params.num_rows == 2:
        repeated_drawing.append(repeated_drawing[0]\
            .mirrorHorizontal(apply_on_copy = True)\
            .translate({'x':body_bottom_right_corner.x,'y':top_right_pin_position.y}))
    repeated_drawing[0].translate({
        'x': body_top_left_corner.x,
        'y': top_left_pin_position.y
    })

    pin_number_0 = series_params.top_pin_number[0]
    pin_name_0 = pinname_update_function(None, pin_number_0)
    repeated_drawing[0].append(
        DrawingPin(at=top_left_pin_position,
                   number=pin_number_0,
                   name=pin_name_0,
                   pin_length=pin_length +
                   (10 if extra_pin == SHIELD_PIN else 0),
                   orientation=DrawingPin.PinOrientation.RIGHT))

    if series_params.num_rows == 2:
        pin_number_1 = series_params.top_pin_number[1](num_pins_per_row)
        pin_name_1 = pinname_update_function(None, pin_number_1)
        repeated_drawing[1].append(
            DrawingPin(at=top_right_pin_position,
                       number=pin_number_1,
                       name=pin_name_1,
                       pin_length=pin_length +
                       (10 if extra_pin == SHIELD_PIN else 0),
                       orientation=DrawingPin.PinOrientation.LEFT))

    drawing.append(
        DrawingArray(
            original=repeated_drawing[0],
            distance={
                'x': 0,
                'y': -pin_spacing_y
            },
            number_of_instances=num_pins_left_side,
            pinnumber_update_function=series_params.pin_number_generator[0],
            pinname_update_function=pinname_update_function))

    if series_params.num_rows == 2:
        drawing.append(
            DrawingArray(original=repeated_drawing[1],
                         distance={
                             'x': 0,
                             'y': -pin_spacing_y
                         },
                         number_of_instances=num_pins_per_row,
                         pinnumber_update_function=series_params.
                         pin_number_generator[1],
                         pinname_update_function=pinname_update_function))

    if series_params.mirror:
        drawing.mirrorHorizontal()

    drawing.appendToSymbol(current_symbol)