def cutoutComponents(board, components): topCutout = extractComponentPolygons(components, "F.CrtYd") for polygon in topCutout: zone = pcbnew.PCB_SHAPE() zone.SetShape(STROKE_T.S_POLYGON) zone.SetPolyShape(shapelyToSHAPE_POLY_SET(polygon)) zone.SetLayer(Layer.F_Paste) board.Add(zone) bottomCutout = extractComponentPolygons(components, "B.CrtYd") for polygon in bottomCutout: zone = pcbnew.PCB_SHAPE() zone.SetShape(STROKE_T.S_POLYGON) zone.SetPolyShape(shapelyToSHAPE_POLY_SET(polygon)) zone.SetLayer(Layer.B_Paste) board.Add(zone)
def make_seg(p1, p2): seg = pcbnew.PCB_SHAPE() seg.SetShape(pcbnew.S_SEGMENT) seg.SetStart(make_point(p1)) seg.SetEnd(make_point(p2)) seg.SetLayer(self.layer) return seg
def kicad_circle(x, y, diameter, layer=pcbnew.Edge_Cuts): """Create and return a KiCad circle centered at x, y.""" item = pcbnew.PCB_SHAPE() item.SetShape(pcbnew.S_CIRCLE) item.SetStart(pcbnew.wxPointMM(x, y)) item.SetEnd(pcbnew.wxPointMM(x + diameter / 2, y)) item.SetLayer(layer) return item
def addLine(board, start, end, thickness): line = pcbnew.PCB_SHAPE() line.SetShape(STROKE_T.S_SEGMENT) line.SetStart(wxPoint(start[0], start[1])) line.SetEnd(wxPoint(end[0], end[1])) line.SetWidth(thickness) line.SetLayer(Layer.F_Paste) board.Add(line) addBottomCounterpart(board, line)
def addHole(board, position, radius): circle = pcbnew.PCB_SHAPE() circle.SetShape(STROKE_T.S_CIRCLE) circle.SetCenter(wxPoint(position[0], position[1])) circle.SetArcStart(wxPoint(position[0], position[1]) + wxPoint(radius/2, 0)) circle.SetWidth(radius) circle.SetLayer(Layer.F_Paste) board.Add(circle) addBottomCounterpart(board, circle)
def build(self, board: pcbnew.BOARD, external_signals: dict[str, pcbnew.NETINFO_ITEM] = {}, path: list[str] = []): """Create and return a KiCad circle centered at x, y.""" item = pcbnew.PCB_SHAPE() item.SetShape(pcbnew.S_CIRCLE) item.SetStart(pcbnew.wxPointMM(self.x, self.y)) item.SetEnd(pcbnew.wxPointMM(self.x + self.diameter / 2, self.y)) item.SetLayer(self.layer) board.Add(item)
def addRoundedCorner(board, center, start, end, thickness): corner = pcbnew.PCB_SHAPE() corner.SetShape(STROKE_T.S_ARC) corner.SetCenter(wxPoint(center[0], center[1])) corner.SetArcStart(wxPoint(start[0], start[1])) if np.cross(start - center, end - center) > 0: corner.SetAngle(fromDegrees(90)) else: corner.SetAngle(fromDegrees(-90)) corner.SetWidth(thickness) corner.SetLayer(Layer.F_Paste) board.Add(corner) addBottomCounterpart(board, corner)
def undoTransformation(point, rotation, origin, translation): """ We apply a transformation "Rotate around origin and then translate" when placing a board. Given a point and original transformation parameters, return the original point position. """ # Abuse PcbNew to do so segment = pcbnew.PCB_SHAPE() segment.SetShape(STROKE_T.S_SEGMENT) segment.SetStart(wxPoint(point[0], point[1])) segment.SetEnd(wxPoint(0, 0)) segment.Move(wxPoint(-translation[0], -translation[1])) segment.Rotate(origin, -rotation) return segment.GetStart()
def _serializeRing(self, ring): coords = list(ring.simplify(pcbnew.FromMM(0.001)).coords) segments = [] # ToDo: Reconstruct arcs if coords[0] != coords[-1]: raise RuntimeError("Ring is incomplete") for a, b in zip(coords, coords[1:]): segment = pcbnew.PCB_SHAPE() segment.SetShape(STROKE_T.S_SEGMENT) segment.SetLayer(Layer.Edge_Cuts) segment.SetStart(roundPoint(a)) segment.SetEnd(roundPoint(b)) segments.append(segment) return segments
def _renderVCutH(self, layer=Layer.Cmts_User): """ return list of PCB_SHAPE V-Cuts """ bBox = self.boardSubstrate.boundingBox() minX, maxX = bBox.GetX() - fromMm( 3), bBox.GetX() + bBox.GetWidth() + fromMm(3) segments = [] for cut in self.hVCuts: segment = pcbnew.PCB_SHAPE() self._setVCutSegmentStyle(segment, layer) segment.SetStart(pcbnew.wxPoint(minX, cut)) segment.SetEnd(pcbnew.wxPoint(maxX, cut)) segments.append(segment) label = pcbnew.PCB_TEXT(segment) self._setVCutLabelStyle(label, layer) label.SetPosition(wxPoint(maxX + fromMm(3), cut)) segments.append(label) return segments
def _renderVCutV(self, layer=Layer.Cmts_User): """ return list of PCB_SHAPE V-Cuts """ bBox = self.boardSubstrate.boundingBox() minY, maxY = bBox.GetY() - fromMm( 3), bBox.GetY() + bBox.GetHeight() + fromMm(3) segments = [] for cut in self.vVCuts: segment = pcbnew.PCB_SHAPE() self._setVCutSegmentStyle(segment, layer) segment.SetStart(pcbnew.wxPoint(cut, minY)) segment.SetEnd(pcbnew.wxPoint(cut, maxY)) segments.append(segment) label = pcbnew.PCB_TEXT(segment) self._setVCutLabelStyle(label, layer) label.SetPosition(wxPoint(cut, minY - fromMm(3))) label.SetTextAngle(900) segments.append(label) return segments
def Run(self): class displayDialog(wx.Dialog): def __init__(self, parent): wx.Dialog.__init__(self, parent, id=-1, title="Add milling") # self.perform_changes = False self.center_x = pcbnew.ToMM( pcbnew.GetBoard().GetDesignSettings().m_GridOrigin[0]) self.center_y = pcbnew.ToMM( pcbnew.GetBoard().GetDesignSettings().m_GridOrigin[1]) self.length_x = 0 self.length_y = 0 self.radius = 0 self.corner_outside = False self.panel = wx.Panel(self) vbox = wx.GridSizer(7, 2, 0, 0) l1 = wx.StaticText(self.panel, -1, "Center X (leave blank for origin):") vbox.Add(l1, 1, wx.ALIGN_RIGHT | wx.ALL, 5) self.t1 = wx.TextCtrl(self.panel) self.t1.Bind(wx.EVT_TEXT, self.OnKeyTyped1) vbox.Add(self.t1, 1, wx.EXPAND | wx.ALIGN_LEFT | wx.ALL, 5) l2 = wx.StaticText(self.panel, -1, "Center Y (leave blank for origin):") vbox.Add(l2, 1, wx.ALIGN_RIGHT | wx.ALL, 5) self.t2 = wx.TextCtrl(self.panel) vbox.Add(self.t2, 1, wx.EXPAND | wx.ALIGN_LEFT | wx.ALL, 5) self.t2.Bind(wx.EVT_TEXT, self.OnKeyTyped2) l3 = wx.StaticText(self.panel, -1, "Length X (mm):") vbox.Add(l3, 1, wx.ALIGN_RIGHT | wx.ALL, 5) self.t3 = wx.TextCtrl(self.panel) vbox.Add(self.t3, 1, wx.EXPAND | wx.ALIGN_LEFT | wx.ALL, 5) self.t3.Bind(wx.EVT_TEXT, self.OnKeyTyped3) l4 = wx.StaticText(self.panel, -1, "Length Y (mm):") vbox.Add(l4, 1, wx.ALIGN_RIGHT | wx.ALL, 5) self.t4 = wx.TextCtrl(self.panel) vbox.Add(self.t4, 1, wx.EXPAND | wx.ALIGN_LEFT | wx.ALL, 5) self.t4.Bind(wx.EVT_TEXT, self.OnKeyTyped4) l5 = wx.StaticText(self.panel, -1, "Tool radius (mm):") vbox.Add(l5, 1, wx.ALIGN_RIGHT | wx.ALL, 5) self.t5 = wx.TextCtrl(self.panel) vbox.Add(self.t5, 1, wx.EXPAND | wx.ALIGN_LEFT | wx.ALL, 5) self.t5.Bind(wx.EVT_TEXT, self.OnKeyTyped5) l6 = wx.StaticText(self.panel, -1, "Corners inside/outside:") vbox.Add(l6, 1, wx.ALIGN_RIGHT | wx.ALL, 5) ApplyToList = ['Inside', 'Outside'] self.t6 = wx.ComboBox(self.panel, choices=ApplyToList) self.t6.SetSelection(0) vbox.Add(self.t6, 0, wx.EXPAND) self.t6.Bind(wx.EVT_COMBOBOX, self.on_hbox6) btn_ok = wx.Button(self.panel, -1, "OK") btn_ok.Bind(wx.EVT_BUTTON, self.on_ok_clicked) vbox.Add(btn_ok, 0, wx.EXPAND) btn_cancel = wx.Button(self.panel, -1, "Cancel") btn_cancel.Bind(wx.EVT_BUTTON, self.on_cancel_clicked) vbox.Add(btn_cancel, 0, wx.EXPAND) self.panel.SetSizer(vbox) self.Centre() self.Show() self.Fit() #---------------------------------------------------------------------- def OnKeyTyped1(self, event): self.center_x = self.retanum( self.t1.GetValue(), pcbnew.ToMM( pcbnew.GetBoard().GetDesignSettings().m_GridOrigin[0])) def OnKeyTyped2(self, event): self.center_y = self.retanum( self.t2.GetValue(), pcbnew.ToMM( pcbnew.GetBoard().GetDesignSettings().m_GridOrigin[1])) def OnKeyTyped3(self, event): self.length_x = self.retanum(self.t3.GetValue()) def OnKeyTyped4(self, event): self.length_y = self.retanum(self.t4.GetValue()) def OnKeyTyped5(self, event): self.radius = self.retanum(self.t5.GetValue()) def on_hbox6(self, event): self.corner_outside = (self.t6.GetSelection > 0) def on_ok_clicked(self, event): self.perform_changes = True self.Destroy() def on_cancel_clicked(self, event): self.perform_changes = False self.Destroy() def retanum(self, n, alternative=0): try: float(n) except ValueError: return alternative return float(n) pcb = pcbnew.GetBoard() frame = displayDialog(None) frame.ShowModal() radius = pcbnew.FromMM(frame.radius) if (radius < 0): radius = 0 center_x = pcbnew.FromMM(frame.center_x) center_y = pcbnew.FromMM(frame.center_y) length_x = pcbnew.FromMM(frame.length_x) length_y = pcbnew.FromMM(frame.length_y) width = pcbnew.FromMM(0.01) if frame.perform_changes and (radius <= length_x / 2) and ( radius <= length_y / 2): if (radius == length_x / 2) and (length_x == length_y): circ = pcbnew.PCB_SHAPE() circ.SetLayer(pcbnew.Edge_Cuts) circ.SetShape(pcbnew.S_CIRCLE) circ.SetArcStart(pcbnew.wxPoint(center_x + radius, center_y)) circ.SetCenter(pcbnew.wxPoint(center_x, center_y)) circ.SetWidth(width) pcb.Add(circ) else: offset = (1 - math.sqrt(2)) if frame.corner_outside else 0 # Draw straight segments if (length_x > 2 * radius): south = pcbnew.PCB_SHAPE() south.SetLayer(pcbnew.Edge_Cuts) south.SetStart( pcbnew.wxPoint((center_x - length_x / 2 + radius - offset * radius), (center_y + length_y / 2))) south.SetEnd( pcbnew.wxPoint( center_x + length_x / 2 - radius + offset * radius, center_y + length_y / 2)) south.SetWidth(width) pcb.Add(south) north = pcbnew.PCB_SHAPE() north.SetLayer(pcbnew.Edge_Cuts) north.SetStart( pcbnew.wxPoint((center_x - length_x / 2 + radius - offset * radius), (center_y - length_y / 2))) north.SetEnd( pcbnew.wxPoint( center_x + length_x / 2 - radius + offset * radius, center_y - length_y / 2)) north.SetWidth(width) pcb.Add(north) if (length_y > 2 * radius): east = pcbnew.PCB_SHAPE() east.SetLayer(pcbnew.Edge_Cuts) east.SetStart( pcbnew.wxPoint( center_x + length_x / 2, center_y - length_y / 2 + radius - offset * radius)) east.SetEnd( pcbnew.wxPoint( center_x + length_x / 2, center_y + length_y / 2 - radius + offset * radius)) east.SetWidth(width) pcb.Add(east) west = pcbnew.PCB_SHAPE() west.SetLayer(pcbnew.Edge_Cuts) west.SetStart( pcbnew.wxPoint( center_x - length_x / 2, center_y - length_y / 2 + radius - offset * radius)) west.SetEnd( pcbnew.wxPoint( center_x - length_x / 2, center_y + length_y / 2 - radius + offset * radius)) west.SetWidth(width) pcb.Add(west) # Draw quarter circles if (radius > 0): if not frame.corner_outside: southeast = pcbnew.PCB_SHAPE() southeast.SetLayer(pcbnew.Edge_Cuts) southeast.SetShape(pcbnew.S_ARC) southeast.SetArcStart( pcbnew.wxPoint(center_x + length_x / 2 - radius, center_y + length_y / 2)) southeast.SetCenter( pcbnew.wxPoint(center_x + length_x / 2 - radius, center_y + length_y / 2 - radius)) southeast.SetAngle(-900) southeast.SetWidth(width) pcb.Add(southeast) northeast = pcbnew.PCB_SHAPE() northeast.SetLayer(pcbnew.Edge_Cuts) northeast.SetShape(pcbnew.S_ARC) northeast.SetArcStart( pcbnew.wxPoint(center_x + length_x / 2, center_y - length_y / 2 + radius)) northeast.SetCenter( pcbnew.wxPoint(center_x + length_x / 2 - radius, center_y - length_y / 2 + radius)) northeast.SetAngle(-900) northeast.SetWidth(width) pcb.Add(northeast) northwest = pcbnew.PCB_SHAPE() northwest.SetLayer(pcbnew.Edge_Cuts) northwest.SetShape(pcbnew.S_ARC) northwest.SetArcStart( pcbnew.wxPoint(center_x - length_x / 2 + radius, center_y - length_y / 2)) northwest.SetCenter( pcbnew.wxPoint(center_x - length_x / 2 + radius, center_y - length_y / 2 + radius)) northwest.SetAngle(-900) northwest.SetWidth(width) pcb.Add(northwest) southwest = pcbnew.PCB_SHAPE() southwest.SetLayer(pcbnew.Edge_Cuts) southwest.SetShape(pcbnew.S_ARC) southwest.SetArcStart( pcbnew.wxPoint(center_x - length_x / 2, center_y + length_y / 2 - radius)) southwest.SetCenter( pcbnew.wxPoint(center_x - length_x / 2 + radius, center_y + length_y / 2 - radius)) southwest.SetAngle(-900) southwest.SetWidth(width) pcb.Add(southwest) else: factor = (1 - math.sqrt(2) / 2) southeast = pcbnew.PCB_SHAPE() southeast.SetLayer(pcbnew.Edge_Cuts) southeast.SetShape(pcbnew.S_ARC) southeast.SetArcStart( pcbnew.wxPoint( center_x + length_x / 2 - radius + offset * radius, center_y + length_y / 2)) southeast.SetCenter( pcbnew.wxPoint( center_x + length_x / 2 - radius + factor * radius, center_y + length_y / 2 - radius + factor * radius)) southeast.SetAngle(-1800) southeast.SetWidth(width) pcb.Add(southeast) northeast = pcbnew.PCB_SHAPE() northeast.SetLayer(pcbnew.Edge_Cuts) northeast.SetShape(pcbnew.S_ARC) northeast.SetArcStart( pcbnew.wxPoint( center_x + length_x / 2, center_y - length_y / 2 + radius - offset * radius)) northeast.SetCenter( pcbnew.wxPoint( center_x + length_x / 2 - radius + factor * radius, center_y - length_y / 2 + radius - factor * radius)) northeast.SetAngle(-1800) northeast.SetWidth(width) pcb.Add(northeast) northwest = pcbnew.PCB_SHAPE() northwest.SetLayer(pcbnew.Edge_Cuts) northwest.SetShape(pcbnew.S_ARC) northwest.SetArcStart( pcbnew.wxPoint( center_x - length_x / 2 + radius - offset * radius, center_y - length_y / 2)) northwest.SetCenter( pcbnew.wxPoint( center_x - length_x / 2 + radius - factor * radius, center_y - length_y / 2 + radius - factor * radius)) northwest.SetAngle(-1800) northwest.SetWidth(width) pcb.Add(northwest) southwest = pcbnew.PCB_SHAPE() southwest.SetLayer(pcbnew.Edge_Cuts) southwest.SetShape(pcbnew.S_ARC) southwest.SetArcStart( pcbnew.wxPoint( center_x - length_x / 2, center_y + length_y / 2 - radius + offset * radius)) southwest.SetCenter( pcbnew.wxPoint( center_x - length_x / 2 + radius - factor * radius, center_y + length_y / 2 - radius + factor * radius)) southwest.SetAngle(-1800) southwest.SetWidth(width) pcb.Add(southwest)
def Run(self): import faceplate_footprint_lib footprint_lib = faceplate_footprint_lib.get_lib_location() railmount_fp = "Faceplate_Rail_Mount_Slot_Plated" SCALE = 1000000.0 msg = "" board = pcbnew.GetBoard() # Find the pcb outline and a list of the drawings on the edgecuts layer pcboutline, edgecuts_dwgs = find_pcb_outline_bbox(board) # Find the center of the pcb outline pcbcenter = pcboutline.Centre() # Move the previous edge cuts to comments layer move_drawings(edgecuts_dwgs, pcbnew.Cmts_User) # Set the fp width to the smallest standard HP size that's larger than the pcb width pcbwidth = pcboutline.GetWidth() fphp, fpwidth = find_width_to_hp(pcbwidth / SCALE) msg += "Faceplate is %d HP wide by 128.5mm high\n" % fphp # Calculate the left and right edges of the faceplate fpleft = pcbcenter.x - fpwidth * SCALE / 2.0 fpright = fpleft + fpwidth * SCALE # Calculate the top and bottom edges of the faceplate (128.5mm height) fpbottom = pcbcenter.y + 128.5 * SCALE / 2.0 fptop = fpbottom - 128.5 * SCALE # Calculate the four corners bottomleft = pcbnew.wxPoint(int(fpleft), int(fpbottom)) bottomright = pcbnew.wxPoint(int(fpright), int(fpbottom)) topleft = pcbnew.wxPoint(int(fpleft), int(fptop)) topright = pcbnew.wxPoint(int(fpright), int(fptop)) # Draw the board outline segments bottomline = pcbnew.PCB_SHAPE(board) board.Add(bottomline) bottomline.SetLayer(pcbnew.Edge_Cuts) bottomline.SetStart(bottomleft) bottomline.SetEnd(bottomright) topline = pcbnew.PCB_SHAPE(board) board.Add(topline) topline.SetLayer(pcbnew.Edge_Cuts) topline.SetStart(topleft) topline.SetEnd(topright) leftline = pcbnew.PCB_SHAPE(board) board.Add(leftline) leftline.SetLayer(pcbnew.Edge_Cuts) leftline.SetStart(topleft) leftline.SetEnd(bottomleft) rightline = pcbnew.PCB_SHAPE(board) board.Add(rightline) rightline.SetLayer(pcbnew.Edge_Cuts) rightline.SetStart(topright) rightline.SetEnd(bottomright) #add rail mount slots railmount_topleft = pcbnew.wxPoint(topleft.x + 0.295 * 25.4 * SCALE, topleft.y + 0.118 * 25.4 * SCALE) railmount_topright = pcbnew.wxPoint(topright.x - 0.295 * 25.4 * SCALE, topright.y + 0.118 * 25.4 * SCALE) railmount_bottomleft = pcbnew.wxPoint( bottomleft.x + 0.295 * 25.4 * SCALE, bottomleft.y - 0.118 * 25.4 * SCALE) railmount_bottomright = pcbnew.wxPoint( bottomright.x - 0.295 * 25.4 * SCALE, bottomright.y - 0.118 * 25.4 * SCALE) mod = pcbnew.FootprintLoad(footprint_lib, railmount_fp) mod.SetPosition(railmount_topleft) board.Add(mod) mod = pcbnew.FootprintLoad(footprint_lib, railmount_fp) mod.SetPosition(railmount_topright) board.Add(mod) mod = pcbnew.FootprintLoad(footprint_lib, railmount_fp) mod.SetPosition(railmount_bottomleft) board.Add(mod) mod = pcbnew.FootprintLoad(footprint_lib, railmount_fp) mod.SetPosition(railmount_bottomright) board.Add(mod) msg += "Creating four rail mount slots (for 8HP and smaller faceplates, delete two of these)" + "\n" msg += "You may need to refresh the display now. Select Legacy mode, then Modern mode" + "\n"