示例#1
0
def pcbfunc(Filename = None):
    if Filename: 
        my_board = pcbnew.LoadBoard (Filename)
    else:
        my_board = pcbnew.GetBoard()

    filename = change_extension (my_board.GetFileName(), ".pos")

    f = open (filename, "w")

    f.write ("### Module positions - created on %s ###" % datetime.datetime.now().strftime("%Y-%m-%d %H:%M"))
    f.write ("### Printed by get_pos v1")
    f.write ("## Unit = mm, Angle = deg.")
    f.write ("## Side : All")
    f.write ("# Ref     Val        Package                PosX       PosY       Rot  Side  Type")

    origin = my_board.GetAuxOrigin()

    # for v5 use GetLibItemName() instead of GetFootprintName()
    for module in my_board.GetModules():
        f.write ("%s \"%s\" %s %1.3f %1.3f %1.3f %s %s" % ( module.GetReference(), 
                                    module.GetValue(),
                                    module.GetFPID().GetFootprintName(),
                                    pcbnew.ToMM(module.GetPosition().x - origin.x),
                                    pcbnew.ToMM(-module.GetPosition().y + origin.y),
                                    module.GetOrientation() / 10.0,
                                    "top" if module.GetLayer() == 0 else "bottom",
                                    get_class ( module.GetAttributes() )
                                    ))

    f.write ("## End")

    f.close ()

    print ("Written to %s" % filename)
示例#2
0
    def BuildThisFootprint(self):

        steps = self.pads["steps"]
        bands = self.pads["bands"]
        touch_width = self.pads["width"]
        touch_length = self.pads["length"]
        touch_clearance = self.pads["clearance"]

        step_length = float(touch_length) / float(steps)

        t_size = self.GetTextSize()
        w_text = self.draw.GetLineThickness()
        ypos = touch_width / 2 + t_size / 2 + w_text
        self.draw.Value(0, -ypos, t_size)
        ypos += t_size + w_text * 2
        self.draw.Reference(0, -ypos, t_size)

        # set SMD attribute
        self.module.SetAttributes(MOD_CMS)

        # starting pad
        band_width = touch_width / bands

        xpos = -0.5 * (steps - 1) * step_length
        ypos = -0.5 * (bands - 1) * band_width

        pos = wxPointMM(pcbnew.ToMM(xpos), pcbnew.ToMM(ypos))

        for b in range(bands):
            self.AddStrip(pos, steps, band_width, step_length, touch_clearance)
            pos += wxPoint(0, band_width)
示例#3
0
 def GetValue(self):
     return "QFP-{nx:g}x{ny:g}_{x:g}x{y:g}_Pitch{p:g}mm".format(
         nx=self.pads['nx'],
         ny=self.pads['ny'],
         x=pcbnew.ToMM(self.package['width']),
         y=pcbnew.ToMM(self.package['height']),
         p=pcbnew.ToMM(self.pads['pitch']))
示例#4
0
 def selfToMainDialog(self):
     self.mainDlg.lstLayer.SetItems(list(self.layerMap.values()))  #maui
     self.mainDlg.lstLayer.SetSelection(self.layerId)
     self.mainDlg.txtNetFilter.SetItems(self.netFilterList)
     self.mainDlg.txtNetFilter.SetSelection(
         self.netFilterList.index(self.netFilter))
     self.mainDlg.txtViaOffset.SetValue(str(pcbnew.ToMM(self.viaOffset)))
     self.mainDlg.txtViaPitch.SetValue(str(pcbnew.ToMM(self.viaPitch)))
     self.mainDlg.txtViaDrill.SetValue(str(pcbnew.ToMM(self.viaDrill)))
     self.mainDlg.txtViaSize.SetValue(str(pcbnew.ToMM(self.viaSize)))
     self.mainDlg.lstViaNet.SetItems(
         [item.GetNetname() for item in self.netMap.values()])
     for i, item in enumerate(self.netMap.values()):
         if self.mainDlg.lstViaNet.GetString(i) in ["GND", "/GND"]:
             self.mainDlg.lstViaNet.SetSelection(i)
             break
     self.mainDlg.chkNetFilter.SetValue(self.isNetFilterChecked)
     self.mainDlg.txtNetFilter.Enable(self.isNetFilterChecked)
     self.mainDlg.chkLayer.SetValue(self.isLayerChecked)
     self.mainDlg.lstLayer.Enable(self.isLayerChecked)
     self.mainDlg.chkIncludeDrawing.SetValue(self.isIncludeDrawingChecked)
     self.mainDlg.chkIncludeSelection.SetValue(
         self.isIncludeSelectionChecked)
     self.mainDlg.chkDebugDump.SetValue(self.isDebugDumpChecked)
     self.mainDlg.chkRemoveViasWithClearanceViolation.SetValue(
         self.isRemoveViasWithClearanceViolationChecked)
     self.mainDlg.chkSameNetZoneViasOnly.SetValue(
         self.isSameNetZoneViasOnlyChecked)
     self.mainDlg.m_buttonDelete.Bind(wx.EVT_BUTTON, self.onDeleteClick)
    def AddYElectrodes(self, touch_length, touch_width, y_width,
                       electrodeName):
        yElectrodeSpacing = 4
        yElectrodeCount = int(
            ((pcbnew.ToMM(touch_width) - 4) / yElectrodeSpacing)) + 1
        yElectrodeThickness = y_width

        currentLayer = pcbnew.F_Cu
        yPosition = (pcbnew.ToMM(touch_width) / 2) - (
            (pcbnew.ToMM(touch_width) -
             ((yElectrodeCount - 1) * yElectrodeSpacing)) / 2.0)

        for i in range(0, yElectrodeCount):
            pad = self.smdRectPad(
                self.module,
                wxSize(touch_length, yElectrodeThickness),
                wxPoint(0, pcbnew.FromMM(yPosition)),
                str(electrodeName),
            )
            self.module.Add(pad)
            yPosition -= yElectrodeSpacing

        # Leftmost line that connects all electrodes
        pad = self.smdRectPad(
            self.module,
            wxSize(
                yElectrodeThickness,
                (yElectrodeCount - 1) * pcbnew.FromMM(yElectrodeSpacing) +
                yElectrodeThickness,
            ),
            wxPoint(-touch_length / 2, 0),
            str(electrodeName),
        )
        self.module.Add(pad)
示例#6
0
    def CheckParameters(self):

        # check that the package is large enough
        width = pcbnew.ToMM(self.parameters['Pads']['pitchX'] *
                            self.parameters['Pads']['columns'])

        length = pcbnew.ToMM(self.parameters['Pads']['pitchY'] *
                             self.parameters['Pads']['rows'])
示例#7
0
 def drill(self):
     if self.type in ('standard', 'hole_not_plated'):
         if self._pad.GetDrillShape() == pcbnew.PAD_DRILL_OBLONG:
             return pcbnew.ToMM(self._pad.GetDrillSize())
         else:
             return pcbnew.ToMM(self._pad.GetDrillSize())[0]
     else:
         return None
    def GetValue(self):

        return "QFN-{n}_{ep}{x:g}x{y:g}_Pitch{p:g}mm".format(
            n=self.pads['n'],
            ep="EP_" if self.epad['epad'] else '',
            x=pcbnew.ToMM(self.package['width']),
            y=pcbnew.ToMM(self.package['height']),
            p=pcbnew.ToMM(self.pads['pitch']))
示例#9
0
    def GetValue(self):

        return "QFN-{n}_{ep}{x:g}x{y:g}mm_Pitch{p:g}mm".format(
            n=2 * (self.pads["pins in X direction"] +
                   self.pads["pins in Y direction"]),
            ep="1EP_" if self.epad['epad'] else '',
            x=pcbnew.ToMM(self.package['width']),
            y=pcbnew.ToMM(self.package['height']),
            p=pcbnew.ToMM(self.pads['pitch']))
示例#10
0
    def get_placement_info(self):
        self.placement_info_top = []
        self.placement_info_bottom = []
        self.numALL = 0
        self.numSMT = 0
        #components = self.get_components()

        origin = self.board.GetAuxOrigin()

        for module in self.board.GetModules():
            reference = module.GetReference()

            #comp = self.get_component_by_ref(components, reference)
            #if comp:
            #    excluded = (self.get_user_field(comp, u'Исключён из ПЭ') != None)
            #else:
            #    excluded = True
            #if excluded:
            #    continue

            if self.is_non_annotated_ref(reference):
                continue

            value = module.GetValue()
            excluded = False
            for ig in IGINOR:
                if value == ig:
                    excluded = True
            if excluded:
                continue

            self.numALL += 1
            package = str(module.GetFPID().GetLibItemName())

            pos = module.GetPosition() - origin

            pos_x = pcbnew.ToMM(pos.x)
            if module.IsFlipped():
                pos_x = -pos_x

            pos_y = -pcbnew.ToMM(pos.y)

            rotation = module.GetOrientationDegrees()

            if module.IsFlipped():
                placement_info = self.placement_info_bottom
            else:
                placement_info = self.placement_info_top

            is_smd = self.is_smd_module(module)
            if is_smd:
                self.numSMT += 1

            placement_info.append(
                [reference, value, package, pos_x, pos_y, rotation, is_smd])

        self.sort_placement_info_by_ref()
示例#11
0
    def CheckParameters(self):

        # check that the package is large enough
        width = pcbnew.ToMM(self.parameters['Pads']['pitch'] * self.parameters['Pads']['columns'])

        length = pcbnew.ToMM(self.parameters['Pads']['pitch'] * self.parameters['Pads']['rows'])

        self.CheckParam('Package','width',min_value=width,info="Package width is too small (< {w}mm)".format(w=width))
        self.CheckParam('Package','length',min_value=length,info="Package length is too small (< {l}mm".format(l=length))
示例#12
0
    def GetValue(self):
        pins = (self.parameters["Pads"]["rows"] * self.parameters["Pads"]["columns"])

        return "BGA-{n}_{a}x{b}_{x}x{y}mm".format(
                n = pins,
                a = self.parameters['Pads']['columns'],
                b = self.parameters['Pads']['rows'],
                x = pcbnew.ToMM(self.parameters['Package']['width']),
                y = pcbnew.ToMM(self.parameters['Package']['length'])
            )
def generate_position_csv(name, output_dir):
    board = pcbnew.LoadBoard(name)
    board_name, ext = os.path.splitext(name)
    print('Position file')

    with open(os.path.join(output_dir, board_name + '-top-pos.csv'), 'w', newline='') as out_top,\
         open(os.path.join(output_dir, board_name + '-bottom-pos.csv'), 'w', newline='') as out_bot:
        fieldnames = ['Ref', 'Val', 'Package', 'PosX', 'PosY', 'Rot', 'Side']
        csv_top = csv.DictWriter(out_top,
                                 fieldnames=fieldnames,
                                 quoting=csv.QUOTE_NONNUMERIC)
        csv_bot = csv.DictWriter(out_bot,
                                 fieldnames=fieldnames,
                                 quoting=csv.QUOTE_NONNUMERIC)
        csv_top.writeheader()
        csv_bot.writeheader()

        def sorted_nicely(l):
            convert = lambda text: int(text) if text.isdigit() else text
            alphanum_key = lambda key: [
                convert(c) for c in re.split('([0-9]+)', key.GetReference())
            ]
            return sorted(l, key=alphanum_key)

        sorted_modules = sorted_nicely(board.GetModules())

        aux_origin = board.GetAuxOrigin()

        for m in sorted_modules:
            is_cms = (m.GetAttributes() == pcbnew.MOD_CMS)
            is_top = not m.IsFlipped()
            is_bot = not is_top

            if not is_cms:
                continue

            side =  'top'     if is_top \
            else    'bottom'  if is_bot \
            else    'none'

            values = {
                'Ref': m.GetReference(),
                'Val': m.GetValue(),
                'Package': m.GetFPID().GetLibItemName(),
                'PosX': pcbnew.ToMM(m.GetPosition().x - aux_origin.x),
                'PosY': pcbnew.ToMM(aux_origin.y - m.GetPosition().y),
                'Rot': m.GetOrientationDegrees(),
                'Side': side,
            }

            if side == 'top':
                csv_top.writerow(values)
            if side == 'bottom':
                csv_bot.writerow(values)
示例#14
0
    def get_placement_info(self):
        self.info = []
        self.numALL = 0 
        self.numSMT = 0 

        origin = self.board.GetAuxOrigin()

        for module in self.board.GetFootprints():
            reference = module.GetReference()

            if self.is_non_annotated_ref(reference):
                continue

            value = module.GetValue()
            excluded = False
            '''

            for ig in IGINOR:
                if value == ig:
                    excluded = True
            if excluded:
                continue
            '''
            
            self.numALL += 1
            package = str(module.GetFPID().GetLibItemName())

            pos = module.GetPosition() - origin

            pos_x = pcbnew.ToMM(pos.x)
            if module.IsFlipped():
                pos_x = -pos_x

            pos_y = -pcbnew.ToMM(pos.y)

            rotation = module.GetOrientationDegrees()

            if module.IsFlipped():
                side = u'bottom'
            else:
                side = u'top'

            is_smd = self.is_smd_module(module)
            smdor = u'HID'
            if is_smd:
                self.numSMT +=1
                smdor = u'SMD'

            self.info.append([reference, value, package, pos_x, pos_y, rotation, side, smdor])

        self.info.sort(key=self.get_ref_num)
        self.info.sort(key=self.get_ref_group)
        self.info.sort(key=self.get_side_group, reverse=True)
 def GetValue(self):
     name = "{0:.2f}_{1:0.2f}_{2:.0f}".format(
         pcbnew.ToMM(self.parameters["Corner"]["width"]),
         pcbnew.ToMM(self.parameters["Corner"]["radius"]),
         (self.parameters["Corner"]["angle"]))
     if not self.parameters["Corner"]["line"]:
         pref = "uwArc"
     else:
         pref = "uwLine"
     if self.parameters["Corner"]["rectangle"]:
         pref += "R"
     return pref + "%s" % name
示例#16
0
    def GetValue(self):
        pins = (self.parameters["Pads"]["rows"] *
                self.parameters["Pads"]["columns"])
        if self.parameters["Pads"]["rowoffsetx"] != 0:
            pins = pins // 2
        pins -= len(self.parameters["Pads"]["missing pads"].split(','))

        return "CSP-{n}_{x}x{y}mm_Layout{cols}x{rows}_P{px}x{py}-missing[{missing}]".format(
            n=pins,
            x=pcbnew.ToMM(self.parameters['Package']['width']),
            y=pcbnew.ToMM(self.parameters['Package']['length']),
            cols=self.parameters['Pads']['columns'],
            rows=self.parameters['Pads']['rows'],
            px=pcbnew.ToMM(self.parameters['Pads']['pitchX']),
            py=pcbnew.ToMM(self.parameters['Pads']['pitchY']),
            missing=self.parameters['Pads']['missing pads'])
示例#17
0
    def get_length(self):
        # current point and layer

        lenght = self.get_new_endpoints(self.start_point, self.start_layer, 0,
                                        self.tracks_on_net, 0, ["pad1"])

        length_alt = []
        resistance = []
        # caluclate again
        size = len(self.track_list)
        for i in range(size):
            length_alt.append(0)
            resistance.append(0)
            for track in self.track_list[i][1:-1]:
                length_alt[i] = length_alt[i] + pcbnew.ToMM(track.GetLength())
                track_res = track.GetLength() / SCALE * (
                    0.0000000168 * 1000) / (0.035 * track.GetWidth() / SCALE)
                resistance[i] = resistance[i] + track_res

        # if connection vas not found, raise an exception
        if not length_alt:
            raise LookupError(
                "Did not find a connection between pads\nThe connection might be partial or through the zone."
            )

        # find minimum and get only that track list
        min_length = min(length_alt)
        min_res = min(resistance)
        index = length_alt.index(min_length)

        # go through the list and find minimum
        min_length = min(lenght)

        return min_length, min_res
示例#18
0
def set_hole_pos_by_sw(pcb, sw_name):
    sw = pcb.FindModuleByReference(sw_name)
    sw_x, sw_y = pcbnew.ToMM(sw.GetPosition())
    hole_name = "HOLE" + str(sw_name.replace("SW", ""))
    hole_obj = pcb.FindModuleByReference(hole_name)
    hole_obj.SetPosition(pcbnew.wxPointMM(sw_x + HOLE_PITCH,
                                          sw_y + HOLE_PITCH))
示例#19
0
def set_diode_position_by_sw(pcb, sw_name):
    sw = pcb.FindModuleByReference(sw_name)
    sw_x, sw_y = pcbnew.ToMM(sw.GetPosition())
    d_name = "D" + str(sw_name.replace("SW", ""))
    d_obj = pcb.FindModuleByReference(d_name)
    d_obj.SetOrientation(ROT_DIODE * 10)
    d_obj.SetPosition(pcbnew.wxPointMM(sw_x + X_OFS, sw_y + Y_OFS))
    def CheckParameters(self):

        pads = self.parameters['Pads']
        numbering = self.parameters['Numbering']
        outline = self.parameters['Outline']
        padRotation = self.parameters['Pad rotation']

        # Check that pads do not overlap
        pad_dia = pcbnew.ToMM(pads['diameter'])
        centres = pcbnew.ToMM(pads['center diameter'])
        n_pads = pads['count']

        self.CheckParam('Pads','diameter',max_value=centres*math.pi/n_pads,info="Pads overlap")

        # Check that the pads fit inside the outline
        d_min = pad_dia + centres

        self.CheckParam("Outline","diameter",min_value=d_min, info="Outline diameter is too small")
示例#21
0
def avoid_mounting_holes(pcb):
    """Just a workaround to avoid mounting holes for some diodes."""
    conflicted_diodes = [2, 3, 8, 9, 14, 15]
    X_OFS_4_HOLE = -float(2.5)
    for c_d in conflicted_diodes:
        d_name = "D{}".format(c_d)
        d = pcb.FindModuleByReference(d_name)
        x, y = pcbnew.ToMM(d.GetPosition())
        d.SetPosition(pcbnew.wxPointMM(x + X_OFS_4_HOLE, y))
示例#22
0
def get_board_properties(filename, chip_ref):
    """
    Returns a dict from netclass name -> (tolerance, nets)
    Where tolerance is maximum difference in matched track lengths.
    And nets is a list of (netname, length) for each net in the netclass.

    Only netclasses with length matching tolerances are returned
    """
    pcb = pcbnew.LoadBoard(filename)
    pcb.BuildListOfNets()  # required so 'pcb' contains valid netclass data

    tolerances = {}
    nets = {}

    tracks = pcb.GetTracks()  # tuples of (netname, classname)
    netclasses = list(set(t.GetNet().GetClassName()
                          for t in tracks))  # unique netclass names

    result = {}

    die_lengths = {}
    pads = pcb.FindModuleByReference(chip_ref).Pads()

    for pad in pads:
        name = pad.GetNetname()
        length = pcbnew.ToMM(pad.GetPadToDieLength())
        die_lengths[name] = length

    for netclass in netclasses:
        tolerance = get_tolerance(netclass)
        if tolerance is None:
            continue
        tracks_netclass = [
            t for t in tracks if t.GetNet().GetClassName() == netclass
        ]  # tracks in this netclass
        netnames = list(set([t.GetNet().GetNetname() for t in tracks_netclass
                             ]))  # unique netnames in this netclass
        netnames.sort()
        nets = [(n,
                 sum(
                     pcbnew.ToMM(t.GetLength()) for t in tracks_netclass
                     if t.GetNet().GetNetname() == n)) for n in netnames]
        result[netclass] = (tolerance, nets)
    return (result, die_lengths)
示例#23
0
def set_trace_widths(board, target_widths):

    board.BuildListOfNets()  # required so 'board' contains valid netclass data
    # build list with copper layer names
    copper_layer_count = board.GetCopperLayerCount()
    layer_names = [
        board.GetLayerName(layer_id)
        for layer_id in range(board.GetCopperLayerCount() - 1)
    ] + [board.GetLayerName(31)]

    # check the target widths structure
    for nc, width_map in target_widths.items():
        # TODO check for valid net class (API only available in kicad 5)
        # nc = board.GetAllNetClasses()
        for layer_name in width_map.keys():
            if layer_name != 'Default' and layer_name not in layer_names:
                raise Exception('Invalid layer name: %s' % layer_name)

    # initialize counters for changes
    count = collections.OrderedDict()
    for layer_name in layer_names:
        count.setdefault(layer_name, 0)

    for track in board.GetTracks():
        for nc, width_map in target_widths.items():
            default_width = width_map['Default']
            if type(track) == pcbnew.TRACK and track.GetNet().GetClassName(
            ) == nc:
                layer_name = track.GetLayerName()
                if layer_name in width_map:
                    track.SetWidth(pcbnew.FromMils(width_map[layer_name]))
                else:
                    if default_width <= 0:
                        pos = track.GetPosition()
                        x = pcbnew.ToMM(pos.x)
                        y = pcbnew.ToMM(pos.y)
                        raise Exception(
                            'Found track on net %s on unexpected layer: %s at position %.2fx%.2f mm'
                            % (track.GetNetname(), layer_name, x, y))
                    else:
                        track.SetWidth(pcbnew.FromMils(default_width))
                count[layer_name] += 1

    return count
示例#24
0
def move_right_modules_left_mirror(x_center, module_corresponts):
    for rl, rr in module_corresponts.items():
        ml = FindModuleByReference(rl)
        mr = FindModuleByReference(rr)
        l_pos = pcbnew.ToMM(ml.GetPosition())
        l_ori = ml.GetOrientationDegrees()
        r_pos = pcbnew.wxPointMM(x_center * 2 - l_pos[0], l_pos[1])
        r_ori = 360 - l_ori
        mr.SetPosition(r_pos)
        mr.SetOrientationDegrees(r_ori)
示例#25
0
def get_centroid_data(parts):
    
    spec_dict = collections.OrderedDict([
            # db_column        header       transform func
            ('reference',     ('RefDes',    lambda x: '"%s"'%x)), 
            ('side',          ('Layer',     lambda x: '"%s"'%x)), 
            ('pos_x',         ('LocationX', lambda x: '"%.4f"'%pcbnew.ToMM(x))), 
            ('pos_y',         ('LocationY', lambda x: '"%.4f"'%pcbnew.ToMM(x))), 
            ('rotation_deg',  ('Rotation',  lambda x: '"%.4f"'%x)), 
            ]) 

    return get_data_str(
            parts,
            spec_dict,
            separator = ',',
            populated_only = True,
            smt_only = True,
            file_doc = 'Units used = mm / deg',
            header_on = True
            )
def WriteToFootprint(name: str, path: str, polygons, createNew: bool = True):
    header = \
    "(module {0} (layer F.Cu,) (tedit 5F08A9C4)\n".format(name) + \
    "  (fp_text reference REF** (at -0.03 -2.63) (layer F.SilkS)\n" + \
    "    (effects (font (size 1 1) (thickness 0.15)))\n" + \
    "  )\n" + \
    "  (fp_text value {} (at 0.08 -4.13) (layer F.Fab) hide\n".format(name) + \
    "  (effects (font (size 1 1) (thickness 0.15)))\n" + \
    "  )\n"
    path = "/home/dom/kicad/FP/test.pretty/"

    dir = QDir(path)
    filePath = dir.absoluteFilePath(name + ".kicad_mod")
    if createNew:
        
        # delete it since we are creating it new
        if (QFile(filePath).exists()):
            LogInfo("Deleting existing footprint at: {}".format(filePath))
            os.remove(filePath)
        fileFP = open(filePath,'w')
        fileFP.write(header)

        # no iterate through the polygon and write
        # pcbnew.DRAWSEGMENT.GetPolyShape().
        # pcbnew.DRAWSEGMENT.BuildPolyPointsList()
        
        # (fp_poly (pts (xy 18.79 0.499) (xy 17.74 0.499) (xy 17.74 -0.501) (xy 18.79 -0.501)) (layer F.Mask) (width 0))

        for polygon in polygons:

            points = polygon.BuildPolyPointsList()
            pcbnew.DRAWSEGMENT
            points_str = ""
            for point in points:
                points_str += " (xy {:.3f} {:.3f})".format(pcbnew.ToMM(point.x),pcbnew.ToMM(point.y))
            fileFP.write("(fp_poly (pts {}) (layer {}) (width {}))".format(points_str, pcbnew.BOARD_GetStandardLayerName(polygon.GetLayer()), polygon.GetWidth()))
        # write the final closing ')'
        fileFP.write("\n)")
        fileFP.close()
示例#27
0
def extractRings(geometryList):
    """
    Walks a list of DRAWSEGMENT entities and produces a lists of continuous
    rings returned as list of list of indices from the geometryList.
    """
    coincidencePoints = {}
    for i, geom in enumerate(geometryList):
        start = toTuple(getStartPoint(geom))
        coincidencePoints.setdefault(start, CoincidenceList()).append(i)
        end = toTuple(getEndPoint(geom))
        coincidencePoints.setdefault(end, CoincidenceList()).append(i)
    for point, items in coincidencePoints.items():
        if len(items) != 2:
            raise RuntimeError("Wrong number of entities ({}) at [{}, {}]".format(
                len(items), pcbnew.ToMM(point[0]), pcbnew.ToMM(point[1])
            ))

    rings = []
    unused = [True] * len(geometryList)
    while any(unused):
        start = getUnused(unused)
        rings.append(findRing(start, geometryList, coincidencePoints, unused))
    return rings
示例#28
0
    def get_pos_props(self, m):
        '''
        gather all module props. in the same format as found in the .pos file

        m: pcbnew.MODULE instance

        returns: a dict like ...
            {
                'description': u'Capacitor,non-Polarized, Chip;1.65mm L X 0.85mm W X 1.00mm H, IPC Medium Density',
                'package': u'CAPC1709X100N',
                'position_mm': (-248.4374, -144.8816),
                'orientation_deg': 0.0,
                'reference': u'C1',
                'side': 'bottom',
                'value': u'CC0603_22UF_6.3V_20%_X5R'
            }
        '''
        layer = m.GetLayer()
        if layer not in (pcbnew.F_Cu, pcbnew.B_Cu):
            raise RuntimeError('on illegal layer: ' + m.GetReference())

        pos = m.GetPosition()
        pos -= self.board.GetAuxOrigin()  # subtract user place offset
        if layer == pcbnew.B_Cu:  # match pcbnew behaviour
            pos.x = -pos.x

        return {
            'description': m.GetDescription(),
            'value': m.GetValue(),
            'reference': m.GetReference(),
            'side': 'top' if layer == pcbnew.F_Cu else 'bottom',
            'package': m.GetFPID().GetLibItemName().wx_str(),
            'orientation_deg': m.GetOrientation() / 10.0,
            # pcbnew has the minus on posy as well
            'position_mm': (pcbnew.ToMM(pos[0]), -pcbnew.ToMM(pos[1]))
        }
示例#29
0
    def print_parameter_table(self):
        for name, section in self.parameters.iteritems():
            print "  %s:" % name

            for key, value in section.iteritems():
                unit = ""
                if (type(value) is int
                        or type(value) is float) and not "*" in key:
                    unit = "mm"

                if "*" in key:
                    key = key[1:]
                else:
                    value = pcbnew.ToMM(value)

                print "    %s: %s%s" % (key, value, unit)
示例#30
0
def arrange_diodes():
    for i in range(1, 46 + 1):
        r = "SW" + str(i)
        sw = FindModuleByReference("SW" + str(i))
        d = FindModuleByReference("D" + str(i))
        angle = sw.GetOrientationDegrees()
        tmp_pos = pcbnew.ToMM(sw.GetPosition())
        sw_pos = MyPosition(tmp_pos[0], tmp_pos[1])
        d_pos = sw_pos + SwitchPosition(0, 0, -angle).up(-0.3).to_mm()
        d.SetPosition(pcbnew.wxPointMM(d_pos.x, d_pos.y))
        d.SetOrientationDegrees(angle)
        # ref position (relative from switch position)
        ref = d.Reference()
        ref.SetTextAngle(0)
        ref_pos_mm = (4.1, 0) if len(str(i)) == 1 else (4.6, 0)
        ref_pos = pcbnew.wxPoint(pcbnew.FromMM(ref_pos_mm[0]),
                                 pcbnew.FromMM(ref_pos_mm[1]))
        ref.SetPos0(ref_pos)