def TaperFootprint(self, center=pcbnew.wxPoint(0,0), angle_deg=0): self.module = pcbnew.MODULE(None) # 6 # 5 +------------+ # | |\ # | | \ 7 # | | +---+ 0 # | | | | # | | +---+ 1 # | | / 2 # | |/ # 4 +------------+ # 3 points = [(self.w2/2, -self.w2/2), (self.w2/2, self.w2/2), (-self.w2/2, self.w2/2), \ (-self.w2/2 - self.tlen, self.w1/2), (-(self.w1/2 + self.tlen + self.w2/2), self.w1/2), \ (-(self.w1/2 + self.tlen + self.w2/2), -self.w1/2), (-self.w2/2 - self.tlen, -self.w1/2), \ (-self.w2/2, -self.w2/2)] points = [pcbnew.wxPoint(*point) for point in points] # Custom pad for smaller W2 x W2 pad cs_pad = pcbnew.D_PAD(self.module) cs_pad.SetSize(pcbnew.wxSize(self.w2, self.w2)) cs_pad.SetShape(pcbnew.PAD_SHAPE_CUSTOM) cs_pad.SetAnchorPadShape(pcbnew.PAD_SHAPE_RECT) cs_pad.SetAttribute(pcbnew.PAD_ATTRIB_SMD) cs_pad.SetLayerSet(pcbnew.LSET(pcbnew.F_Cu)) cs_pad.AddPrimitive(points, 0) cs_pad.SetLocalClearance(1) cs_pad.SetNet(self.net) cs_pad.SetPadName("1") self.module.Add(cs_pad) self.module.Add(Layout.smdRectPad(self.module, pcbnew.wxSize(self.w1, self.w1), pcbnew.wxPoint(-(self.w1/2 + self.tlen + self.w2/2), 0), "1", angle_deg, self.net)) # TODO: Address other layers... self.module.SetPosition(center) # Add to pcbnew pcbnew.GetBoard().Add(self.module) pcbnew.Refresh()
def ChamferFootprint(self, center=pcbnew.wxPoint(0, 0)): self.module = pcbnew.MODULE(None) # Create new module self.angle = m.radians(self.angle_deg) # Calculate the miter w = self.width # Width of the corner from edge of the corner to inside corner corner_width = pcbnew.ToMM(w) / m.cos(self.angle / 2) # Get proportion of width to cut cut = self.OptimalMiter() print("Cut: {0:.2f}%".format(cut * 100)) # Distance from uncut outside corner point to point 7 cut = pcbnew.FromMM(cut * corner_width / m.cos( (m.pi - self.angle) / 2)) # Distance between points 2 and 3 and points 3 and 4 # Minimum of w/2 to satisfy DRC, otherwise pads are too close # and track connected to other pad overlaps the other one. # Rounded trace end can also stick out of the cut area # if a is too small. a = max(cut - self.width * m.tan(self.angle / 2), w / 2) # Distance between points 3 and 4 x34 = a * m.sin(self.angle) y34 = a * m.cos(self.angle) # Distance between points 4 and 5 x45 = self.width * m.cos(self.angle) y45 = self.width * m.sin(self.angle) # Distance from point 7 to 1 (no x-component) d71 = a + self.width * m.tan(self.angle / 2) - cut # 1 2 # +--+ # | |3 # 7 \ --+ 4 # \ | # \--+ 5 # 6 dW = w / 55 # To prevent tracks from over-extending points = [ (-w / 2, -d71 / 2), (w / 2, -d71 / 2), (w / 2, a - d71 / 2 + dW), (w / 2 + x34 - (d71 / 2 - d71 / 1e5 - dW) * m.sin(self.angle), a + y34 - d71 / 2 - (d71 / 2 - d71 / 1e5 - dW) * m.cos(self.angle) + dW), (w / 2 + x34 - x45 - (d71 / 2 - d71 / 1e5 - dW) * m.sin(self.angle), a + y34 + y45 - d71 / 2 - (d71 / 2 - d71 / 1e5 - dW) * m.cos(self.angle) + dW), (cut * m.sin(self.angle) - w / 2, a + self.width * m.tan(self.angle / 2) + cut * m.cos(self.angle) - d71 / 2 + dW), (-w / 2, a + self.width * m.tan(self.angle / 2) - cut - d71 / 2 + dW) ] # Last two points can be equal if points[-2] == points[-1]: points = points[:-1] points = [pcbnew.wxPoint(*point) for point in points] # Custom pad cs_pad = pcbnew.D_PAD(self.module) cs_pad.SetSize(pcbnew.wxSize(w, d71)) cs_pad.SetShape(pcbnew.PAD_SHAPE_CUSTOM) cs_pad.SetAnchorPadShape(pcbnew.PAD_SHAPE_RECT) cs_pad.SetAttribute(pcbnew.PAD_ATTRIB_SMD) cs_pad.SetLayerSet(pcbnew.LSET(pcbnew.F_Cu)) cs_pad.AddPrimitive(points, 0) cs_pad.SetLocalClearance(1) cs_pad.SetNet(self.net) cs_pad.SetPadName("1") self.module.Add(cs_pad) # Halfway between points 4 and 5 posx = ((w / 2 + x34) + (w / 2 + x34 - x45)) / 2 posy = ((a + y34 - d71 / 2) + (a + y34 + y45 - d71 / 2)) / 2 # Position pad so that pad edge touches polygon edge posx -= (d71 / 2 - dW) * m.sin(self.angle) posy -= (d71 / 2 - dW) * m.cos(self.angle) - dW size_pad = pcbnew.wxSize(d71, w) self.module.Add( Layout.smdRectPad(self.module, pcbnew.wxSize(w, d71), pcbnew.wxPoint(0, 0), "1", 0, self.net)) # Alignment pad self.module.Add( Layout.smdRectPad(self.module, size_pad, pcbnew.wxPoint(posx, posy), "1", (self.angle_deg - 90) * 10, self.net)) self.module.Rotate(self.module.GetPosition(), (90 + self.angle_deg) * 100) # self.module.MoveAnchorPosition(pcbnew.wxPoint((d71/2 - a - w/2)*m.sin(self.angle), \ # (d71/2 - a - w/2)*m.cos(self.angle))) self.module.SetPosition(center) if self.layer == pcbnew.B_Cu: self.module.Flip(self.module.GetCenter()) elif self.layer == pcbnew.F_Cu: self.module.Rotate(self.module.GetPosition(), (90 + self.angle_deg) * 100) # Find center of bounding box for placement # Add to Pcbnew pcbnew.GetBoard().Add(self.module) pcbnew.Refresh()