Source code for Swoop.tools.SwoopTools

from Swoop import EagleFile
import Swoop


[docs]class ScanLayersVisitor(Swoop.EagleFilePartVisitor): """A visitor to scan the file for all :class:`EagleFilePart` objects a :code:`layer` attribute and collected the names of all layers that are used somewhere in the file. """ def __init__(self, efp): Swoop.EagleFilePartVisitor.__init__(self,efp) self.foundLayers = set() self.definedLayers = set() def default_pre(self, efp): if "layer" in efp.__dict__ and efp.layer is not None: assert type(efp.layer) == str self.foundLayers.add(efp.layer) def Layer_pre(self, efp): assert type(efp) == Swoop.Layer self.definedLayers.add(efp.name)
[docs] def getUsedLayers(self): """ Get a list of the names of layers used in the file. :rtype: List of :code:`str` """ return list(self.foundLayers)
[docs] def getUnusedLayers(self): """ Get a list containing the names of unused layers. :rtype: List of :code:`str` """ return list(self.definedLayers - self.foundLayers)
[docs] def getDefinedLayers(self): """ Get a list of all the layers defined in the file. :rtype: List of :code:`str` """ return list(self.definedLayers)
[docs]class ScanLibraryReferences(Swoop.EagleFilePartVisitor): """A visitor to scan an :class:`EagleFile` object and identify all the library components (Libraries, Symbols, Packages, Devicesets, and Devices) that are referenced in the file. """ def __init__(self, efp): Swoop.EagleFilePartVisitor.__init__(self,efp) self.usedEFPs = set() def Part_pre(self, efp): self.usedEFPs.add(efp.get_library()) self.usedEFPs.add(efp.get_deviceset()) self.usedEFPs.add(efp.get_device()) if efp.get_device().get_package(): self.usedEFPs.add(efp.get_device().get_package()) for i in efp.get_deviceset().get_gates(): self.usedEFPs.add(i.get_symbol()) def Element_pre(self, efp): raise NotImplementedError("Support for scanning board files not implemented yet")
[docs] def get_referenced_efps(self): """ Return a list of all the library components that are used. :rtype: List of :class:`EagleFilePart` """ return list(self.usedEFPs)
class DumpVisitor(Swoop.EagleFilePartVisitor): def __init__(self, efp): Swoop.EagleFilePartVisitor.__init__(self,efp) def default_pre(self, efp): print "pre " + type(efp).__name__ def default_post(self, efp): print "pre " + type(efp).__name__
[docs]def mergeLayers(src, dst, force=False): """ Merge layers from the :class:`EagleFile` :code:`src` into :class:`EagleFile` :code:`dst`. If there is some conflict between the two (different names for the same layer number or vice versa), then raise an exception (unless :code:`force == True`) :param src: The :class:`EagleFile` to update. :param dst: The :class:`EagleFile` to draw layers from. :param force: If :code:`True` overwrite the layers. Otherwise, throw an :class:`SwoopError` on conflict. """ for srcLayer in src.get_layers().values(): for dstLayer in dst.get_layers().values(): if ((srcLayer.name == dstLayer.name and srcLayer.number != dstLayer.number) or (srcLayer.name != dstLayer.name and srcLayer.number == dstLayer.number)): if force: try: src.remove_layer(dstLayer) except: pass else: raise Swoop.SwoopError("Layer mismatch: " + str(src.filename) + " <" + str(srcLayer.number) + ", '" + str(srcLayer.name) +"'>; " + str(dst.filename) +" = <" + str(dstLayer.number) + ", '" + str(dstLayer.name) +"'>;") if srcLayer.name not in dst.get_layers(): dst.add_layer(srcLayer.clone())
[docs]def normalizeLayers(ef, layers, force=False): """Clean up layers in a file. First, remove all unused layers, then merge in the layers from :class:`EagleFile` object :code:`layers`. If :code:`force == True`, overwrite layers in :code:`ef` with the layers even if there is a conflict. :param ef: The :class:`EagleFile` to update. :param layers: The :class:`EagleFile` to draw layers from. :param force: If :code:`True` overwrite the layers. Otherwise, throw an :class:`SwoopError` on conflict. """ for i in ScanLayersVisitor(ef).go().getUnusedLayers(): #print "removed " + str(i) ef.remove_layer(i) mergeLayers(layers, ef, force)
[docs]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 pad = (Swoop.From(sch). get_parts(). with_name(pinref.get_part()). find_device(). get_connects(). with_gate(pinref.gate). with_pin(pinref.pin). get_pad().first()) assert pad is not None brd.get_signal(name).add_contactref(Swoop.Contactref(). set_element(pinref.get_part()). set_pad(pad))
[docs]def propagatePartToBoard(part, brd): """ Copy :code:`part` to ``brd`` by creating a new :class:`Element` and populating it accordingly. If the part already exists, it will be replaced. .. Note:: This function doesn't update the board's signals. You can run :meth:`rebuildBoardConnections` to do that. :param part: :class:`Part` object that to propagate. :param brd: Destination :class`BoardFile`. :rtype: :code:`None` """ n =(Swoop.Element(). set_name(part.get_name()). set_library(part.get_library()). set_package(part. find_package(). get_name() ). set_value(part.get_value()). set_x(0). set_y(0)) for a in part.find_technology().get_attributes(): n.add_attribute(a.clone(). set_display("off"). set_layer("Document"). set_in_library(False)) for a in part.get_attributes(): n.add_attribute(a.clone(). set_display("off"). set_layer("Document")) brd.add_element(n)