示例#1
0
    def check_routing(self):
        with NestedError(self.errors, self.brd.get_filename()):

            unrouted = Swoop.From(
                self.brd).get_signals().get_wires().with_width(0.0)
            if unrouted.count() > 0:
                self.error(u"You have unrouted nets: {}".format(" ".join(
                    map(output_format,
                        unrouted.get_parent().unique().sort()))),
                           inexcusable=True)

            routed_wires = Swoop.From(
                self.brd).get_signals().get_wires().without_width(0.0)

            self.check_intersections(routed_wires)

            for w in routed_wires:
                with NestedError(self.errors, w):
                    x1, y1, x2, y2 = w.get_points()

                    if abs(x1 - x2) < 0.1 or abs(y1 - y2) < 0.1 or abs(
                            abs(x1 - x2) -
                            abs(y1 - y2)) < 0.1 or w.get_length() < 2:
                        pass
                    else:
                        self.warn(
                            "Net routed at odd angle: {} centered at ({}, {}) in layer {}.  Net should only be vertical, horizontal, or diagonal (i.e., 45 degrees)."
                            .format(output_format(w.get_parent()),
                                    (x1 + x2) / 2, (y1 + y2) / 2,
                                    w.get_layer()))
示例#2
0
def rename_part(old, new, schematic=None, board=None):
    """Rename a part in a schematic and the corresponding board, if provided.
    Change the name of the part and update all references to it.
    
    :param schematic: The :class:`SchematicFile` in which to do the renaming
    :param board: The :class:`BoardFile` in which to do the renaming (optional)
    :param old: Old part name.
    :param new: New part name.

    """

    if schematic is not None:
        old_part = schematic.get_part(old)
        old_part.set_name(new)

        for i in Swoop.From(schematic).get_sheets().get_instances():
            if i.get_part().upper() == old.upper():
                i.set_part(new.upper())

        for pinref in Swoop.From(schematic).get_sheets().get_nets(
        ).get_segments().get_pinrefs():
            if pinref.get_part().upper() == old.upper():
                pinref.set_part(new.upper())

    if board is not None:
        for e in Swoop.From(board).get_elements():
            if e.get_name().upper() == old.upper():
                e.set_name(new.upper())

        for contact_ref in Swoop.From(board).get_signals().get_contactrefs():
            if contact_ref.get_element().upper() == old.upper():
                contact_ref.set_element(new.upper())
示例#3
0
    def do_match(self, path, pattern, solutions):
        if len(pattern) == 0:
            solutions.append(path)
            return
        tail = path[-1]

        if isinstance(tail, Swoop.Part):

            if len(pattern) == 2:
                pin_link = pattern[0]
                assert isinstance(pin_link, Pin)
                net_link = pattern[1]
                assert isinstance(net_link, Net), "{}".format(net_link)

                nets = (Swoop.From(
                    self.sch).get_sheets().get_nets().filtered_by(
                        lambda x: net_link.match(x)).get_segments().
                        get_pinrefs().filtered_by(
                            lambda x: pin_link.match(x) and x.get_part(
                            ) == tail.get_name()).get_parent().get_parent())
                for n in nets:
                    self.do_match(path + [n], pattern[2:], solutions)

            elif len(pattern) > 2:
                initial_pin_link = pattern[0]
                assert isinstance(initial_pin_link, Pin)
                net_link = pattern[1]
                assert isinstance(net_link, Net)
                terminal_pin_link = pattern[2]
                assert isinstance(terminal_pin_link, Pin)
                part_link = pattern[3]
                assert isinstance(part_link, Part), "Bad pattern: {}".format(
                    str_pattern(pattern=pattern))

                nets = (Swoop.From(self.sch).get_sheets().get_nets(
                ).filtered_by(lambda x: net_link.match(x)).get_segments(
                ).get_pinrefs().filtered_by(lambda x: x.get_part(
                ) == tail.get_name()).get_parent().get_parent().unique())

                for n in nets:
                    refs = (Swoop.From(n).get_segments().get_pinrefs())
                    initial_pin_matches = refs.filtered_by(
                        lambda x: initial_pin_link.match(x) and x.get_part(
                        ) == tail.get_name())
                    terminal_pin_matches = refs.filtered_by(
                        lambda x: terminal_pin_link.match(x))

                    if (len(initial_pin_matches)):
                        parts = map(lambda x: self.sch.get_part(x),
                                    terminal_pin_matches.get_part())
                        for p in parts:
                            if part_link.match(p) and p != tail:
                                self.do_match(path + [n, p], pattern[4:],
                                              solutions)

            else:
                raise Exception("Couldn't process pattern {}".format(
                    str_pattern(path, pattern)))
        else:
            raise Exception("Patterns must start with a part.")
示例#4
0
    def match(self, pattern):
        solutions = []

        for i in range(0, len(pattern)):
            if isinstance(pattern[i], Swoop.Part):
                pattern[i] = Part(part=pattern[i])
            elif isinstance(pattern[i], Swoop.Net):
                pattern[i] = Net(net=pattern[i])

        link = pattern[0]
        if isinstance(link, Part):
            options = Swoop.From(
                self.sch).get_parts().filtered_by(lambda x: link.match(x))
        elif isinstance(link, Net):
            options = Swoop.From(self.sch).get_sheets().get_nets().filtered_by(
                lambda x: link.match(x))
        else:
            raise Exception(
                "First link in pattern must be Net or Part: {}".format(link))

        for o in options:
            path = [o]
            self.do_match(path, pattern[1:], solutions)

        return solutions
示例#5
0
    def check_names(self):
        parts = Swoop.From(self.sch).get_parts().filtered_by(
            lambda x: "$" in x.get_name()).sort()
        if parts:
            self.warn(
                "These parts have '$' in their names.  Parts should all have nice, pretty names.  Either set the prefix on the device or name it yourself: {}"
                .format(" ".join(map(output_format, parts))),
                inexcusable=True)

        labeled_nets = Swoop.From(self.sch).get_sheets().get_nets(
        ).get_segments().get_labels().get_parent().get_parent().filtered_by(
            lambda x: '$' in x.get_name()).sort()

        if labeled_nets.count():
            self.warn(
                "These nets have labels on them and have '$' in their names.  Labeled nets should have meaningful names: {}"
                .format(" ".join(map(output_format, labeled_nets))),
                inexcusable=True)

        net_names = set(
            Swoop.From(self.sch).get_sheets().get_nets().get_name())
        part_names = set(Swoop.From(self.sch).get_parts().get_name())

        i = net_names.intersection(part_names)
        if i:
            self.warn(
                "The following are names of both a net and part.  That's confusing: {}"
                .format(", ".join(map(lambda x: "'{}'".format(x), i))),
                inexcusable=True)
示例#6
0
    def check_deviceset(self, ds, power_and_ground):
        with NestedError(self.errors, ds):
            gates = Swoop.From(ds).get_gates()

            if len(gates) == 1:
                if gates[0].get_x() != 0 or gates[0].get_y() != 0:
                    self.warn(
                        u"In the left pane of the device window, the schematic symbol for device should be at origin (0,0) instead of ({} ,{})."
                        .format(gates[0].get_x(), gates[0].get_y()),
                        inexcusable=True)

            if ds.get_name() not in power_and_ground:
                if ds.get_uservalue():
                    if len(
                            Swoop.From(ds).get_gates().find_symbol().
                            get_drawing_elements().with_type(
                                Swoop.Text).with_text(
                                    lambda x: x.upper() == ">VALUE")) == 0:
                        self.warn(
                            u"Device has user value (look for a check box at the bottom of the device editor window), but symbol does not include '>VALUE'.  This means the value will not visible in the schematic."
                        )

            for device in ds.get_devices():
                value_labels = Swoop.From(
                    device).find_package().get_drawing_elements().with_type(
                        Swoop.Text).with_text(
                            lambda x: x.upper() == ">VALUE").count()

                if ds.get_uservalue() and value_labels == 0:
                    self.warn(
                        u"Device has user value (look for a check box at the bottom of the device editor window), but package for variant '{}' does not include '>VALUE'.  This means the value will not be visible in the board."
                        .format(device.get_name()))
                if not ds.get_uservalue() and value_labels > 0:
                    self.warn(
                        u"Device does not have user value (look for a check box at the bottom of the device editor window), but package for variant '{}' includes '>VALUE'.  This means the package name will appear on the board, which is probably not what you want."
                        .format(device.get_name()))

            for d in ds.get_devices():
                if d.get_package() is not None:
                    with NestedError(self.errors, d):
                        t = d.get_technology("")
                        if not t:
                            self.warn(
                                "{} does not have a default technology".format(
                                    d.get_name()))
                            continue
                        for a in self.required_deviceset_attributes:
                            if t.get_attribute(
                                    a) is None or not t.get_attribute(
                                        a).get_value():
                                self.warn(
                                    u"Missing required attribute '{}'".format(
                                        a),
                                    inexcusable=True)
                            elif not t.get_attribute(a).get_constant():
                                self.warn(
                                    u"Attribute '{}' should be constant.".
                                    format(a),
                                    inexcusable=True)
示例#7
0
    def test_Detach(self):

        brd = self.brd.clone()

        (Swoop.From(brd).get_layers().with_name(Swoop.matching("^t")).detach())

        self.assertEqual(
            Swoop.From(brd).get_layers().count(), 56, "Detach Error")
示例#8
0
    def check_frame(self):
        if not Swoop.From(self.sch).get_parts().with_deviceset("FRAME_B_L"):
            self.warn(u"You don't have a frame around your schematic.")

        if Swoop.From(self.sch).get_sheets().get_plain_elements().with_layer(
                "Info") < 5:
            self.warn(
                u"You don't have enough documentation (items in layer 'Info') on your schematic.  If your schematic is very simple, you can provide that as an explanation for why no documentation is needed."
            )
示例#9
0
def copy_deviceset(deviceset, to_lib):
    """Copy :code:`deviceset` and all associated packages and symbols to :code:`to_lib`.  Fail if there are any name conflicts.

    """

    for p in Swoop.From(deviceset).get_devices().find_package():
        to_lib.add_package(p.clone())
    for s in Swoop.From(deviceset).get_gates().find_symbol():
        to_lib.add_symbol(s.clone())
    to_lib.add_deviceset(deviceset.clone())
示例#10
0
def consolidate_parts_in_schematic(schematic,
                                   lib_name,
                                   part_names=None,
                                   ignore_conflicts=False):
    """
    Create a new library called :code:`lib_name` in :code:`schematic` that the
    information for the parts listed in :code:`part_names`.  Check for
    conflicting names.

    Update the parts to refer to the new libray. 

    Warning:  This will make the schematic inconsistent with the board (if one exists).

    :param schematic: A :class:`SchematicFile` object to operate on.
    :param lib_name: The name of the new library.
    :param part_names: An array of part names (i.e., reference designators).  If :code:`None` then do all the parts.  Defaults to :code:`None`.
    :returns:  Nothing.
    """

    if schematic.get_library(lib_name) is None:
        lib = Swoop.Library().set_name(lib_name)
        schematic.add_library(lib)
    else:
        lib = schematic.get_library(lib_name)

    src_lib = {}

    def check_for_conflicts(name, lib):
        if name in src_lib:
            assert src_lib[name] == lib, "Name '{}' in both {} and {}".format(
                name, lib, src_lib[name])
        else:
            src_lib[name] = lib

    for p in Swoop.From(schematic).get_parts().filtered_by(
            lambda x: part_names is None or x.get_name() in part_names):
        package = p.find_device().find_package()
        if package is not None:
            if not ignore_conflicts:
                check_for_conflicts(package.get_name(), p.get_library())

        for s in Swoop.From(p).find_deviceset().get_gates().find_symbol():
            if not ignore_conflicts:
                check_for_conflicts(s.get_name(), p.get_library())

        if not ignore_conflicts:
            check_for_conflicts(p.find_deviceset().get_name(), p.get_library())

        copy_deviceset(p.find_deviceset(), lib)

        p.set_library(lib_name)

    return lib
示例#11
0
    def test_ConstantAttrs(self):
        sch = self.sch.clone()

        a = Swoop.From(sch).get_libraries().get_devicesets().get_devices(
        ).get_technologies().get_attributes()[0]

        self.assertEqual(
            a.get_xml(),
            '<attribute name="CASE" value="" constant="no"/>'.encode('utf8'))
        a.set_constant(True)
        self.assertEqual(a.get_xml(),
                         '<attribute name="CASE" value=""/>'.encode('utf8'))
        a.set_constant(False)
        self.assertEqual(
            a.get_xml(),
            '<attribute name="CASE" value="" constant="no"/>'.encode('utf8'))

        brd = self.brd.clone()
        c1a = brd.get_element("C1A")
        c1b = brd.get_element("C1B")
        c1 = brd.get_element("C1")

        self.assertEqual(c1a.get_locked(), True)
        self.assertEqual(c1b.get_locked(), False)
        self.assertEqual(c1.get_locked(), False)
示例#12
0
def consolidate_libraries_in_schematic(schematic,
                                       new_lib_name,
                                       lib_names,
                                       cleanup=False):
    """Create a new library called :code:`new_lib_name` in :code:`schematic` that the
    information for all the parts from libraries listed in :code:`lib_names`.

    Update the parts to refer to the new libray.  If :code:`remove_libs` is
    :code:`True`, then remove the old libraries from the schematic.

    Warning:  This will make the schematic inconsistent with the board (if one exists).

    :param schematic: A :class:`SchematicFile` object to operate on.
    :param new_lib_name: The name of the new library.
    :param lib_names: An array of library names to remove.
    :param remove_libs: Should we remove the libraries in :code:`lib_names` after consolidation?
    :returns:  The new :code:`Library` object in :code:`schematic'

    """

    part_names = Swoop.From(schematic).get_parts().filtered_by(
        lambda x: x.get_library() in lib_names).get_name().unique()
    lib = consolidate_parts_in_schematic(schematic, new_lib_name, part_names)

    if cleanup:
        removeDeadEFPs(schematic)

    return lib
示例#13
0
    def check_connections(self):
        parts = self.match([
            Part(select=lambda x: count_pins(x) == 2,
                 description="a two-terminal device")
        ])

        for p in parts:
            p = p[0]

            for g in Swoop.From(p).find_deviceset().get_gates():
                for n in Swoop.From(self.sch).get_sheets().get_nets():
                    if Swoop.From(n).get_segments().get_pinrefs().with_part(
                            p.get_name()).with_gate(g.get_name()).count() == 2:
                        self.error(
                            "Both pins on {} are connected to the same net ({})."
                            .format(output_format(p), output_format(n)))
示例#14
0
    def check_pours(self):
        with self.errors.nest(self.brd.get_filename()):

            for p in Swoop.From(self.brd).get_signals().get_polygons():
                if p.get_isolate() not in [0, 0.0, None]:
                    self.warn(
                        "A pour in {} has non-zero 'isolate'.  This is unusual, and probably not what you want."
                        .format(p.get_parent().get_name()))
示例#15
0
    def check_outline(self):
        with self.errors.nest(self.brd.get_filename()):
            dims = Swoop.From(self.brd).get_plain_elements().with_type(
                Swoop.Wire).with_layer("Dimension")
            self.info("Found {} lines in layer 'Dimension'".format(len(dims)))
            if dims.filtered_by(lambda x: x.get_width() < 0.01).count():
                self.warn(
                    "Lines in 'Dimension' should have width >= 0.01mm.  Otherwise some CAM viewers have trouble displaying them the board outline.",
                    inexcusable=True)

            non_wire = Swoop.From(self.brd).get_plain_elements().without_type(
                Swoop.Hole).without_type(Swoop.Wire).without_type(
                    Swoop.Circle).with_layer("Dimension")
            if len(non_wire):
                self.warn(
                    "You things in your Dimension layer other than lines, arcs, and circles.  You probably don't want that.",
                    inexcusable=True)
示例#16
0
 def check_names(self):
     with self.errors.nest(self.brd.get_filename()):
         for p in Swoop.From(self.brd).get_elements().get_name():
             m = re.match("[A-Z][A-Z]?\d+", p)
             if not m and self.sch.get_part(p):
                 self.warn(
                     "The name of part '{}' is too long.  It should be at most two capital letters followed numbers."
                     .format(p))
示例#17
0
def updateLibrary(eagleFile, library):
    """
    Add :code:`library` to :code'eagleFile', overwriting it if it's already
    there.  If it's a schematic, it will add the whole library.  For boards, it
    just adds the packages.

    :param eagleFile: A :class:`SchematicFile` or :class:`BoardFile`.
    :param library: The :class:`Library` to add.
    :returns: Nothing

    """
    l = library.get_library().clone()

    if isinstance(eagleFile, Swoop.BoardFile):
        Swoop.From(l).get_library().get_symbols().detach()
        Swoop.From(l).get_library().get_devicesets().detach()

    eagleFile.add_library(l)
示例#18
0
 def check_vias(self):
     with self.errors.nest(self.brd.get_filename()):
         for s in Swoop.From(self.brd.get_signals()):
             for v in s.get_vias():
                 if v.get_drill() > 0.8:
                     self.warn(
                         "The via at ({},{}) on {} is too big ({}mm). You probably don't want vias larger than 0.8mm"
                         .format(v.get_x(), v.get_y(), output_format(s),
                                 v.get_drill()))
示例#19
0
    def do_check(self):
        for library in self.lbrs:
            if isinstance(library, Swoop.LibraryFile):
                name = library.get_filename()
                library = library.get_library()
            else:
                name = library.get_name()

            if name in (self.options.get("skipped_lbrs") or []):
                return

            with NestedError(self.errors, name):
                self.info("Examined {}".format(name))
                fix = self.fix

                if fix:
                    for t in Swoop.From(library).get_devicesets().get_devices(
                    ).get_technologies():
                        for attr in self.required_deviceset_attributes:
                            if not t.get_attribute(
                                    attr) or not t.get_attribute(
                                        attr).get_value():
                                t.add_attribute(Swoop.Attribute().set_name(
                                    attr).set_value("Unknown"))

                    for p in library.get_packages():
                        if not Swoop.From(
                                p).get_drawing_elements().without_type(
                                    Swoop.Hole).with_layer("tKeepout").count():
                            p.add_drawing_element(
                                Swoop.Wire().set_x1(0).set_y1(0).set_x2(0).
                                set_y2(0).set_width(1).set_layer("tKeepout"))

                for s in Swoop.From(library).get_symbols():
                    self.check_symbol(s,
                                      checker_options.power_and_ground_names)

                for p in Swoop.From(library).get_packages():
                    self.check_package(p)

                for ds in Swoop.From(library).get_devicesets():
                    self.check_deviceset(
                        ds, checker_options.power_and_ground_names)
示例#20
0
    def check_parts(self):

        # alignment
        alignment = 25.4 / 10 / 4
        for i in Swoop.From(self.sch).get_sheets().get_instances():

            x1 = i.get_x()
            y1 = i.get_y()
            if not self.is_aligned(x1, alignment) or not self.is_aligned(
                    y1, alignment):
                if self.fix:
                    i.set_x(math.ceil(x1 / alignment) * alignment)
                    i.set_y(math.ceil(y1 / alignment) * alignment)
                else:
                    self.warn("{} not aligned to {}\" grid".format(
                        output_format(i.find_part()), alignment / 25.4),
                              inexcusable=True)

        # check for mismatched values
        for p in Swoop.From(self.sch).get_parts():
            attribute = p.find_technology().get_attribute("VALUE")
            if attribute and attribute.get_value() != p.get_value():
                self.warn(
                    "Part {} has a pre-set value ({}) but you have set a different value ({}).  "
                    "This is probably an error, since the value won't match the part the device's "
                    "attributes describe.".format(p.get_name(),
                                                  attribute.get_value(),
                                                  p.get_value()))

        for p in Swoop.From(self.sch).get_parts():
            # The right solution here is to count the number of pins on the the part.  If there are only 1 or 0 pins, then its not an error if just 1 or 0 pins are connected.
            if Swoop.From(p).find_deviceset().get_gates().find_symbol(
            ).get_pins().count() not in [
                    0, 1
            ]:  # not in checker_options.power_and_ground_names + ["ANTENNA", "FRAME_B_L", "MOUNTING-HOLE"] and "VIA" not in p.get_deviceset():
                if Swoop.From(self.sch).get_sheets().get_nets().get_segments(
                ).get_pinrefs().filtered_by(
                        lambda x: x.get_part() == p.get_name()).count() in [
                            0, 1
                        ]:
                    self.warn("Part {} has 1 or zero nets attached.".format(
                        output_format(p)))
示例#21
0
    def test_Rekey(self):
        sch = self.sch.clone()
        brd = self.brd.clone()
        s = Swoop.From(sch).get_libraries().get_symbols()[0]
        l = s.get_parent()

        old = s.get_name()
        self.assertEqual(l.get_symbol(old), s, "Rename precondition error")
        s.set_name("foo")
        self.assertEqual(s.get_name(), "foo", "Rename error")
        self.assertEqual(l.get_symbol("foo"), s, "Rename error")
        self.assertEqual(l.get_symbol(old), None, "Rename error")
        l.check_sanity()
示例#22
0
    def get_geometry(self, layer_query=None, **options):
        brd = Swoop.From(self)

        wires = self._do_polygonize_wires(
            brd.get_plain_elements().with_type(Wire),
            layer_query=layer_query,
            **options)

        parts = (brd.get_elements() +
                 brd.get_plain_elements().without_type(Wire) +
                 brd.get_signals().get_wires() + brd.get_signals().get_vias())

        return shapely.ops.unary_union(
            parts.get_geometry(layer_query=layer_query, **options) + [wires])
示例#23
0
def rebuildBoardConnections(sch, brd):
    """
    Update the signals in :code:`brd` to match the nets in :code:`sch`.  This will set up the connections, but won't draw the air wires.  You can use Eagle's :code:`ripup` command to rebuild those.

    :param sch: :class:`SchematicFile` object and source of the connection information.
    :param brd: :class:`BoardFile` destination for then connection information.
    :rtype: :code:`None`
    
    """
    #sheets/*/net.name:
    for name in Swoop.From(sch).get_sheets().get_nets().get_name():
        sig = brd.get_signal(name)
        if sig is None:
            brd.add_signal(Swoop.Signal().set_name(name).set_airwireshidden(
                False).set_class("0"))  # We need to do something smarter here.
        else:
            sig.clear_contactrefs()

        for pinref in (Swoop.From(sch).get_sheets().get_nets().with_name(
                name).get_segments().get_pinrefs()):

            if sch.get_part(pinref.part).find_device().get_package() is None:
                continue

            pads = (Swoop.From(sch).get_parts().with_name(
                pinref.get_part()).find_device().get_connects().with_gate(
                    pinref.gate).with_pin(pinref.pin).get_pads())

            assert pads is not None
            if pads is None:
                log.warn("Can't find pads for '{}:{}.{}' on net '{}'".format(
                    pinref.get_part(), pinref.gate, pinref.pin, name))

            for pad in pads:
                brd.get_signal(name).add_contactref(
                    Swoop.Contactref().set_element(
                        pinref.get_part()).set_pad(pad))
示例#24
0
    def check_placement(self):
        with self.errors.nest(self.brd.get_filename()):
            for e in Swoop.From(self.brd).get_elements():
                grid = 0.5
                if self.check_alignment(e, grid):
                    self.warn(
                        "Part {} at ({}, {}) is not not aligned to {}mm grid.".
                        format(e.get_name(), e.get_x(), e.get_y(), grid))

                for a in Swoop.From(e).get_attributes().with_display(True):
                    if a.get_name() == "VALUE" and a.get_value() in [
                            "", None
                    ]:  # If value is "" then it doesn't show up and there is really no way to fix it in eagle.
                        continue
                    grid = 0.1
                    if self.check_alignment(a, grid):
                        if self.fix:
                            a.set_x(round(a.get_x() / grid) * grid)
                            a.set_y(round(a.get_y() / grid) * grid)
                        else:
                            self.warn(
                                "Label '{}' of {} at ({}, {}) in layer {} is not aligned to {}mm grid. "
                                .format(a.get_name(), e.get_name(), a.get_x(),
                                        a.get_y(), a.get_layer(), grid))
示例#25
0
    def do_check(self):
        if not self.sch:
            return

        with NestedError(self.errors, self.sch.get_filename()):
            self.check_supply_symbols()
            self.check_names()
            self.check_libraries()
            self.check_nets()
            self.check_frame()
            self.check_parts()
            self.check_connections()
            LibraryLint(lbrs=Swoop.From(self.sch).get_libraries(),
                        errors=self.errors,
                        fix=self.fix,
                        options=self.options).check()
示例#26
0
    def do_check(self):
        if not self.brd:
            return

        self.check_routing()
        self.check_libraries()
        self.check_outline()
        self.check_names()
        self.check_placement()
        self.check_vias()
        self.check_pours()
        self.check_displayed_attributes()

        LibraryLint(lbrs=Swoop.From(self.brd).get_libraries(),
                    errors=self.errors,
                    fix=self.fix,
                    options=self.options).check()
示例#27
0
    def get_geometry(self, layer_query=None, **options):
        package = Swoop.From(self)

        if "polygonize_wires" in options:
            pw = options["polygonize_wires"]
        else:
            pw = ShapelyEagleFilePart.POLYGONIZE_NONE

        wires = self._do_polygonize_wires(
            package.get_drawing_elements().with_type(Wire),
            layer_query=layer_query,
            **options)

        parts = (package.get_drawing_elements().without_type(Wire) +
                 package.get_smds() + package.get_pads())

        return shapely.ops.unary_union(
            parts.get_geometry(layer_query=layer_query, **options) + [wires])
示例#28
0
    def get_overlapping(self,
                        rectangle_or_xmin,
                        ymin=None,
                        xmax=None,
                        ymax=None):
        from CGAL.CGAL_Kernel import \
            Segment_2,\
            Polygon_2,\
            Point_2,\
            Bbox_2,\
            Iso_rectangle_2,\
            do_intersect
        if isinstance(rectangle_or_xmin, Rectangle):
            query = Iso_rectangle_2(*rectangle_or_xmin.bounds_tuple)
        else:
            query = Iso_rectangle_2(rectangle_or_xmin, ymin, xmax, ymax)

        return Swoop.From(
            [x.swoop_elem for x in self._elements if x.overlaps(query)])
示例#29
0
def quick_bom(schematic):
    """
    Create a dictionary that maps part names to a dictionary contain all the part's attributes in addition to the following extra attributes:

    * :code:`"refdes"`:  The reference designator for the part.
    * :code:`"device"`:  The device name for the part.
    * :code:`"variant"`: The variant name for the part.
    
    :param schematic: The :class:`SchematicFile` to process.
    """
    parts = {}

    for p in Swoop.From(schematic).get_parts():
        attrs = p.get_all_attributes()
        attrs["refdes"] = p.get_name()
        attrs["device"] = p.get_deviceset()
        attrs["variant"] = p.get_device()
        parts[p.get_name()] = attrs
    return parts
示例#30
0
def main():
    parser = argparse.ArgumentParser(description="Update layer numbers.")
    parser.add_argument("--file", required=True,  type=str, nargs='+', dest='file', help="Files with layer numbers you want to change")
    parser.add_argument("--layers", required=True, type=str, dest='layers', help="File with layer numbers you want")
    parser.add_argument("-v", required=False, action='store_true', dest='verbose', help="Be verbose")
    parser.add_argument("-n", required=False, action='store_true', dest='dry_run', help="Don't overwrite anything")

    args = parser.parse_args()

    if args.verbose:
        log.basicConfig(format="%(levelname)s: %(message)s", level=log.DEBUG)
        log.info("Verbose output.")
    else:
        log.basicConfig(format="%(levelname)s: %(message)s")

    layers = Swoop.LibraryFile.from_file(args.layers)
    new_layers = Swoop.From(layers).get_layers()

    for f in args.file:
        ef = Swoop.EagleFile.from_file(f)

        for newl in new_layers:
            try:
                oldl = ef.get_layer(newl.get_name())
            except:
                continue
            if oldl.get_number() != newl.get_number():
                try:
                    t = ef.get_layer(int(newl.get_number()))
                except:
                    t = None
                if t is not None:
                    log.error("Layer number conflict on {} in {}".format(newl.get_number(), f))
                    raise Exception

                log.info("Changed layer '{}' from {} to {} in {}".format(oldl.get_name(), oldl.get_number(), newl.get_number(), f))
                oldl.set_number(newl.get_number())

        if not args.dry_run:
            ef.write(f)