footprint generators python plugins: fix a few issues, and make them more compliant with the KiCad Library Convention 0.11

This commit is contained in:
jean-pierre charras 2015-10-29 18:35:52 +01:00
parent 77f1d8a848
commit ad2c4b807b
9 changed files with 164 additions and 193 deletions

View File

@ -16,7 +16,7 @@
from __future__ import division
import pcbnew
import FootprintWizardDrawingAids as FpWDA
import HelpfulFootprintWizardPlugin as HFPW
@ -28,9 +28,6 @@ class FPC_FootprintWizard(HFPW.HelpfulFootprintWizardPlugin):
def GetDescription(self):
return "FPC (SMT connector) Footprint Wizard"
def GetReferencePrefix(self):
return "J"
def GetValue(self):
pins = self.parameters["Pads"]["*n"]
return "FPC_%d" % pins
@ -77,14 +74,15 @@ class FPC_FootprintWizard(HFPW.HelpfulFootprintWizardPlugin):
offsetX = pad_pitch * ( pad_count-1 ) / 2
size_pad = pcbnew.wxSize( pad_width, pad_height )
size_shld = pcbnew.wxSize(shl_width, shl_height)
size_text = pcbnew.FromMM( 0.8 )
size_text = self.GetTextSize() # IPC nominal
textposy = pad_height/2 + pcbnew.FromMM(1)
self.draw.Value( 0, textposy, size_text )
textposy = textposy + pcbnew.FromMM( 1.2 )
# Gives a position and size to ref and value texts:
textposy = pad_height/2 + pcbnew.FromMM(1) + self.GetTextThickness()
self.draw.Reference( 0, textposy, size_text )
textposy = textposy + size_text + self.GetTextThickness()
self.draw.Value( 0, textposy, size_text )
# create a pad array and add it to the module
for n in range ( 0, pad_count ):
xpos = pad_pitch*n - offsetX
@ -103,74 +101,56 @@ class FPC_FootprintWizard(HFPW.HelpfulFootprintWizardPlugin):
self.module.Add(pad_s0)
self.module.Add(pad_s1)
#add outline
outline = pcbnew.EDGE_MODULE(self.module)
linewidth = pcbnew.FromMM(0.2)
outline.SetWidth(linewidth)
margin = pcbnew.FromMM(0.2)
# add footprint outline
linewidth = self.draw.GetLineTickness()
margin = linewidth
# upper line
posy = -pad_height/2 - linewidth/2 - margin
xstart = - pad_pitch*0.5-offsetX
xend = pad_pitch * pad_count + xstart;
outline.SetStartEnd( pcbnew.wxPoint(xstart, posy), pcbnew.wxPoint( xend, posy) )
outline.SetLayer(pcbnew.F_SilkS) #default: not needed
outline.SetShape(pcbnew.S_SEGMENT)
self.module.Add(outline)
self.draw.Line( xstart, posy, xend, posy )
# lower line
outline1 = outline.Duplicate() #copy all settings from outline
posy = pad_height/2 + linewidth/2 + margin
outline1.SetStartEnd(pcbnew.wxPoint(xstart, posy), pcbnew.wxPoint( xend, posy))
self.module.Add(outline1)
self.draw.Line(xstart, posy, xend, posy)
# around left mechanical pad (the outline around right pad is mirrored/y axix)
outline2 = outline.Duplicate() # vertical segment
yend = pad_s0_pos.y + shl_height/2 + margin
outline2.SetStartEnd(pcbnew.wxPoint(xstart, posy), pcbnew.wxPoint( xstart, yend))
self.module.Add(outline2)
outline2_d = pcbnew.EDGE_MODULE(self.module) # right pad side
outline2_d.Copy(outline2)
outline2_d.SetStartEnd(pcbnew.wxPoint(-xstart, posy), pcbnew.wxPoint( -xstart, yend))
self.module.Add(outline2_d)
self.draw.Line(xstart, posy, xstart, yend)
self.draw.Line(-xstart, posy, -xstart, yend)
outline3 = outline.Duplicate() # horizontal segment below the pad
posy = yend
xend = pad_s0_pos.x - (shl_width/2 + linewidth + margin*2)
outline3.SetStartEnd(pcbnew.wxPoint(xstart, posy), pcbnew.wxPoint( xend, posy))
self.module.Add(outline3)
outline3_d = pcbnew.EDGE_MODULE(self.module) # right pad side
outline3_d.Copy(outline3)
outline3_d.SetStartEnd(pcbnew.wxPoint(-xstart, posy), pcbnew.wxPoint( -xend, yend))
self.module.Add(outline3_d)
self.draw.Line(xstart, posy, xend, posy)
outline4 = outline.Duplicate() # vertical segment at left of the pad
# right pad side
self.draw.Line(-xstart, posy, -xend, yend)
# vertical segment at left of the pad
xstart = xend
yend = posy - (shl_height + linewidth + margin*2)
outline4.SetStartEnd(pcbnew.wxPoint(xstart, posy), pcbnew.wxPoint( xend, yend))
self.module.Add(outline4)
outline4_d = outline.Duplicate() # right pad side
outline4_d.SetStartEnd(pcbnew.wxPoint(-xstart, posy), pcbnew.wxPoint( -xend, yend))
self.module.Add(outline4_d)
self.draw.Line(xstart, posy, xend, yend)
outline5 = outline.Duplicate() # horizontal segment above the pad
# right pad side
self.draw.Line(-xstart, posy, -xend, yend)
# horizontal segment above the pad
xstart = xend
xend = - pad_pitch*0.5-offsetX
posy = yend
outline5.SetStartEnd(pcbnew.wxPoint(xstart, posy), pcbnew.wxPoint( xend, yend))
self.module.Add(outline5)
outline5_d = outline.Duplicate() # right pad side
outline5_d.SetStartEnd(pcbnew.wxPoint(-xstart, posy), pcbnew.wxPoint( -xend, yend))
self.module.Add(outline5_d)
self.draw.Line(xstart, posy, xend, yend)
outline6 = outline.Duplicate() # vertical segment above the pad
# right pad side
self.draw.Line(-xstart, posy,-xend, yend)
# vertical segment above the pad
xstart = xend
yend = -pad_height/2 - linewidth/2 - margin
outline6.SetStartEnd(pcbnew.wxPoint(xstart, posy), pcbnew.wxPoint( xend, yend))
self.module.Add(outline6)
outline6_d = outline.Duplicate() # right pad side
outline6_d.SetStartEnd(pcbnew.wxPoint(-xstart, posy), pcbnew.wxPoint( -xend, yend))
self.module.Add(outline6_d)
self.draw.Line(xstart, posy, xend, yend)
# right pad side
self.draw.Line(-xstart, posy, -xend, yend)
FPC_FootprintWizard().register()

View File

@ -26,7 +26,7 @@ class FootprintWizardDrawingAids:
footprint wizards
A "drawing context" is provided which can be used to set and retain
settings such as line width and layer
settings such as line tickness and layer
"""
# directions (in degrees, compass-like)
@ -47,12 +47,21 @@ class FootprintWizardDrawingAids:
xfrmIDENTITY = [1, 0, 0, 0, 1, 0] # no transform
# these values come from our KiCad Library Convention 0.11
defaultLineThickness = pcbnew.FromMM(0.15)
def DefaultGraphicLayer(self):
return pcbnew.F_SilkS
def DefaultTextValueLayer(self):
return pcbnew.F_Fab
def __init__(self, module):
self.module = module
# drawing context defaults
self.dc = {
'layer': pcbnew.F_SilkS,
'width': pcbnew.FromMM(0.2),
'layer': self.DefaultGraphicLayer(),
'lineThickness': self.defaultLineThickness,
'transforms': [],
'transform': self.xfrmIDENTITY
}
@ -231,18 +240,18 @@ class FootprintWizardDrawingAids:
return pcbnew.wxPoint(x * mat[0] + y * mat[1] + mat[2],
x * mat[3] + y * mat[4] + mat[5])
def SetWidth(self, width):
def SetLineTickness(self, lineThickness):
"""
Set the current pen width used for subsequent drawing
Set the current pen lineThickness used for subsequent drawing
operations
"""
self.dc['width'] = width
self.dc['lineThickness'] = lineThickness
def GetWidth(self):
def GetLineTickness(self):
"""
Get the current drawing context width
Get the current drawing context line tickness
"""
return self.dc['width']
return self.dc['lineThickness']
def SetLayer(self, layer):
"""
@ -251,14 +260,19 @@ class FootprintWizardDrawingAids:
"""
self.dc['layer'] = layer
def GetLayer(self):
"""
return the current drawing layer, used drawing operations
"""
return self.dc['layer']
def Line(self, x1, y1, x2, y2):
"""
Draw a line from (x1, y1) to (x2, y2)
"""
outline = pcbnew.EDGE_MODULE(self.module)
outline.SetWidth(self.dc['width'])
outline.SetLayer(self.dc['layer'])
outline.SetWidth(self.GetLineTickness())
outline.SetLayer(self.GetLayer())
outline.SetShape(pcbnew.S_SEGMENT)
start = self.TransformPoint(x1, y1)
end = self.TransformPoint(x2, y2)
@ -268,8 +282,7 @@ class FootprintWizardDrawingAids:
def Circle(self, x, y, r, filled=False):
"""
Draw a circle at (x,y) of radius r
If filled is true, the width and radius of the line will be set
If filled is true, the thickness and radius of the line will be set
such that the circle appears filled
"""
circle = pcbnew.EDGE_MODULE(self.module)
@ -279,7 +292,7 @@ class FootprintWizardDrawingAids:
circle.SetWidth(r)
end = self.TransformPoint(x, y + r/2)
else:
circle.SetWidth(self.dc['width'])
circle.SetWidth(self.dc['lineThickness'])
end = self.TransformPoint(x, y + r)
circle.SetLayer(self.dc['layer'])
@ -297,7 +310,7 @@ class FootprintWizardDrawingAids:
circular arc (eg a horzontal scale)
"""
circle = pcbnew.EDGE_MODULE(self.module)
circle.SetWidth(self.dc['width'])
circle.SetWidth(self.dc['lineThickness'])
center = self.TransformPoint(cx, cy)
start = self.TransformPoint(sx, sy)
@ -379,6 +392,7 @@ class FootprintWizardDrawingAids:
self.module.Value().SetPos0(self.TransformPoint(x, y))
self.module.Value().SetTextPosition(self.module.Value().GetPos0())
self.module.Value().SetSize(text_size)
self.module.Value().SetLayer(self.DefaultTextValueLayer())
def Box(self, x, y, w, h):
"""

View File

@ -184,7 +184,7 @@ class FootprintWizardParameterManager:
return
if max_value is not None and (
self.parameters[section][param] > min_value):
self.parameters[section][param] > max_value):
self.parameter_errors[section][param] = (
"Must be less than or equal to %d" % (max_value))
return
@ -241,8 +241,9 @@ class HelpfulFootprintWizardPlugin(pcbnew.FootprintWizardPlugin,
def GetValue(self):
raise NotImplementedError
# this value come from our KiCad Library Convention 0.11
def GetReferencePrefix(self):
return "U" # footprints needing wizards of often ICs
return "REF"
def GetImage(self):
return ""
@ -258,7 +259,7 @@ class HelpfulFootprintWizardPlugin(pcbnew.FootprintWizardPlugin,
Thicker than IPC guidelines (10% of text height = 0.12mm)
as 5 wires/mm is a common silk screen limitation
"""
return pcbnew.FromMM(0.2)
return pcbnew.FromMM(0.15)
def SetModule3DModel(self):
"""

View File

@ -38,7 +38,6 @@ class BGAWizard(HFPW.HelpfulFootprintWizardPlugin):
return "Ball Grid Array Footprint Wizard"
def GenerateParameterList(self):
self.AddParam("Pads", "pad pitch", self.uMM, 1)
self.AddParam("Pads", "pad size", self.uMM, 0.5)
self.AddParam("Pads", "row count", self.uNatural, 5)
@ -47,20 +46,15 @@ class BGAWizard(HFPW.HelpfulFootprintWizardPlugin):
self.AddParam("Pads", "outline y margin", self.uMM, 1)
def CheckParameters(self):
self.CheckParamInt("Pads", "*row count")
self.CheckParamInt("Pads", "*column count")
def GetValue(self):
pins = (self.parameters["Pads"]["*row count"]
* self.parameters["Pads"]["*column count"])
return "BGA_%d" % pins
def GetReferencePrefix(self):
return "U"
def BuildThisFootprint(self):
pads = self.parameters["Pads"]
@ -90,10 +84,10 @@ class BGAWizard(HFPW.HelpfulFootprintWizardPlugin):
pads["outline x margin"])
#reference and value
text_size = pcbnew.FromMM(1.2) # IPC nominal
self.draw.Value(0, - ssy - text_size, text_size)
self.draw.Reference(0, ssy + text_size, text_size)
text_size = self.GetTextSize() # IPC nominal
ypos = ssy + text_size
self.draw.Value(0, ypos, text_size)
self.draw.Reference(0, -ypos, text_size)
BGAWizard().register()

View File

@ -47,10 +47,8 @@ class circular_pad_array_wizard(HFPW.HelpfulFootprintWizardPlugin):
self.CheckParamBool("Pads", "*number clockwise")
def GetValue(self):
return "A"
def GetReference(self):
return ""
pins = self.parameters["Pads"]["*n"]
return "CPA_%d" % pins
def BuildThisFootprint(self):
@ -73,5 +71,15 @@ class circular_pad_array_wizard(HFPW.HelpfulFootprintWizardPlugin):
array.AddPadsToModule(self.draw)
body_radius = (prm['circle diameter'] + prm['pad width'])/2 + self.draw.GetLineTickness()
self.draw.Circle(0, 0, body_radius)
text_size = self.GetTextSize() # IPC nominal
thickness = self.GetTextThickness()
textposy = body_radius + self.draw.GetLineTickness()/2 + self.GetTextSize()/2 + thickness
self.draw.Value( 0, textposy, text_size )
self.draw.Reference( 0, -textposy, text_size )
circular_pad_array_wizard().register()

View File

@ -27,7 +27,7 @@ class QFPWizard(HelpfulFootprintWizardPlugin.HelpfulFootprintWizardPlugin):
return "QFP"
def GetDescription(self):
return "QFP Footprint Wizard"
return "Quad Flat Package footprint wizard"
def GenerateParameterList(self):
self.AddParam("Pads", "n", self.uNatural, 100)
@ -108,11 +108,10 @@ class QFPWizard(HelpfulFootprintWizardPlugin.HelpfulFootprintWizardPlugin):
self.draw.Polyline([(inner, lim_y), (lim_x, lim_y), (lim_x, inner)])
#reference and value
text_size = pcbnew.FromMM(1.2) # IPC nominal
text_size = self.GetTextSize() # IPC nominal
text_offset = v_pitch / 2 + text_size + pad_length / 2
self.draw.Value(0, -text_offset, text_size)
self.draw.Reference(0, text_offset, text_size)
self.draw.Value(0, text_offset, text_size)
self.draw.Reference(0, -text_offset, text_size)
QFPWizard().register()

View File

@ -33,14 +33,13 @@ class RowedGridArray(PA.PadGridArray):
class RowedFootprint(HFPW.HelpfulFootprintWizardPlugin):
def GenerateParameterList(self):
# defaults for a DIP package
self.AddParam("Pads", "n", self.uNatural, 24)
self.AddParam("Pads", "silk screen inside", self.uBool, False)
self.AddParam("Pads", "row count", self.uNatural, 2)
def CheckParameters(self):
self.CheckParamInt("Pads", "*row count")
self.CheckParamInt("Pads", "*row count", min_value=1, max_value=2)
self.CheckParamInt(
"Pads", "*n",
is_multiple_of=self.parameters["Pads"]["*row count"])
@ -49,11 +48,8 @@ class RowedFootprint(HFPW.HelpfulFootprintWizardPlugin):
self.CheckParamBool("Pads", "*silk screen inside")
def BuildThisFootprint(self):
pads = self.parameters["Pads"]
num_pads = pads["*n"]
pad_length = pads["pad length"]
pad_width = pads["pad width"]
row_pitch = pads["row spacing"]
@ -61,7 +57,6 @@ class RowedFootprint(HFPW.HelpfulFootprintWizardPlugin):
num_rows = pads["*row count"]
pads_per_row = num_pads // num_rows
row_length = pad_pitch * (pads_per_row - 1) # fenceposts
# add in the pads
@ -92,7 +87,7 @@ class RowedFootprint(HFPW.HelpfulFootprintWizardPlugin):
self.DrawBox(ssx, ssy)
#reference and value
text_size = pcbnew.FromMM(1.2) # IPC nominal
text_size = self.GetTextSize() # IPC nominal
self.draw.Value(0, - ssy - text_size, text_size)
self.draw.Reference(0, ssy + text_size, text_size)
@ -118,15 +113,12 @@ class SDIPWizard(RowedFootprint):
self.AddParam("Pads", "outline y margin", self.uMM, 1)
def GetValue(self):
rows = self.parameters["Pads"]["*row count"]
if rows == 1:
name = "SIP"
elif rows == 2:
else:
name = "DIP"
else: # triple and up aren't really a thing, but call it something!
name = "xIP"
return "%s-%d" % (name, self.parameters["Pads"]["*n"])

View File

@ -24,23 +24,35 @@
#
from pcbnew import *
import HelpfulFootprintWizardPlugin as HFPW
class TouchSliderWizard(FootprintWizardPlugin):
def __init__(self):
FootprintWizardPlugin.__init__(self)
self.name = "Touch Slider"
self.description = "Capacitive Touch Slider Wizard"
self.parameters = {
"Pads":
{"*steps":4, # not internal (measurement) units preceded by "*"
"*bands":2,
"width": FromMM(10),
"length": FromMM(50),
"clearance": FromMM(1)
}
}
self.ClearErrors()
class TouchSliderWizard(HFPW.HelpfulFootprintWizardPlugin):
def GetName(self):
"""
Return footprint name.
This is specific to each footprint class, you need to implement this
"""
return 'Touch Slider'
def GetDescription(self):
"""
Return footprint description.
This is specific to each footprint class, you need to implement this
"""
return 'Capacitive Touch Slider wizard'
def GetValue(self):
steps = int(self.parameters["Pads"]["*steps"])
return "TS"+str(steps)
def GenerateParameterList(self):
self.AddParam("Pads", "steps", self.uNatural, 4)
self.AddParam("Pads", "bands", self.uNatural, 2)
self.AddParam("Pads", "width", self.uMM, 10)
self.AddParam("Pads", "length", self.uMM, 50)
self.AddParam("Pads", "clearance", self.uMM, 1)
# build a rectangular pad
def smdRectPad(self,module,size,pos,name):
@ -70,28 +82,18 @@ class TouchSliderWizard(FootprintWizardPlugin):
# This method checks the parameters provided to wizard and set errors
def CheckParameters(self):
p = self.parameters
steps = p["Pads"]["*steps"]
errors = ""
if (steps<1):
self.parameter_errors["Pads"]["*steps"]="Must be positive"
errors +="Pads/*steps has wrong value"
p["Pads"]["*steps"] = int(pads) # make sure it stays as int (default is float)
prms = self.parameters["Pads"]
steps = prms["*steps"]
bands = prms["*bands"]
bands = p["Pads"]["*bands"]
if steps < 1:
self.parameter_errors["Pads"]["*steps"]="steps must be positive"
if bands < 1:
self.parameter_errors["Pads"]["*bands"]="bands must be positive"
if (bands<1):
self.parameter_errors["Pads"]["*bands"]="Must be positive"
errors +="Pads/*bands has wrong value"
p["Pads"]["*bands"] = int(bands) # make sure it stays as int (default is float)
touch_width = p["Pads"]["width"]
touch_length = p["Pads"]["length"]
touch_clearance = p["Pads"]["clearance"]
return errors
touch_width = prms["width"]
touch_length = prms["length"]
touch_clearance = prms["clearance"]
# The start pad is made of a rectangular pad plus a couple of
# triangular pads facing tips on the middle/right of the first
@ -173,50 +175,31 @@ class TouchSliderWizard(FootprintWizardPlugin):
self.AddFinalPad(pos,touch_width,step_length,touch_clearance,str(steps))
# build the footprint from parameters
# FIX ME: the X and Y position of the footprint can be better.
def BuildThisFootprint(self):
module = MODULE(None) # create a new module
self.module = module
p = self.parameters
steps = int(p["Pads"]["*steps"])
bands = int(p["Pads"]["*bands"])
touch_width = p["Pads"]["width"]
touch_length = p["Pads"]["length"]
touch_clearance = p["Pads"]["clearance"]
prm = self.parameters["Pads"]
steps = int(prm["*steps"])
bands = int(prm["*bands"])
touch_width = prm["width"]
touch_length = prm["length"]
touch_clearance = prm["clearance"]
step_length = float(touch_length) / float(steps)
size_text = wxSize( FromMM( 1), FromMM( 1) );
module.SetReference("TS"+str(steps)) # give it a reference name
module.Reference().SetPos0(wxPointMM(0,-2))
module.Reference().SetTextPosition(module.Reference().GetPos0())
module.Reference().SetSize( size_text );
module.SetValue("Val**") # give it a value
module.Value().SetPos0(wxPointMM(0,-3.2))
module.Value().SetTextPosition(module.Value().GetPos0())
module.Value().SetSize( size_text );
t_size = self.GetTextSize()
w_text = self.draw.GetLineTickness()
ypos = touch_width/(bands*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)
# starting pad
pos = wxPointMM(0,0)
band_width = touch_width/bands
for b in range(bands):
self.AddStrip(pos,steps,band_width,step_length,touch_clearance)
pos+=wxPoint(0,band_width)
fpid = FPID(self.module.GetReference()) #the name in library
module.SetFPID( fpid )
def register():
# create our footprint wizard
touch_slider_wizard = TouchSliderWizard()
# register it into pcbnew
touch_slider_wizard.register()
return touch_slider_wizard
pos += wxPoint(0,band_width)
TouchSliderWizard().register()

View File

@ -97,7 +97,7 @@ class Uss39Wizard(HelpfulFootprintWizardPlugin.HelpfulFootprintWizardPlugin):
def __drawSpace__(self, bit, x):
self.draw.SetLayer(B.F_SilkS)
self.draw.SetWidth(self.X)
self.draw.SetLineTickness(self.X)
self.draw.Line(x, 0, x, self.H)
if (bit == 1):
self.draw.Line(x + self.X, 0, x + self.X, self.H)
@ -122,7 +122,7 @@ class Uss39Wizard(HelpfulFootprintWizardPlugin.HelpfulFootprintWizardPlugin):
def drawQuietZone(self, x0, y0, width, height):
self.draw.SetLayer(B.F_SilkS)
self.draw.SetWidth(self.X)
self.draw.SetLineTickness(self.X)
for offset in range(0, int(self.Q), int(self.X/2)):
xoffset = offset + self.X
@ -139,7 +139,7 @@ class Uss39Wizard(HelpfulFootprintWizardPlugin.HelpfulFootprintWizardPlugin):
self.drawQuietZone(0, 0, x, self.H)
# Draw courtyard origin
self.draw.SetLayer(B.F_CrtYd)
self.draw.SetWidth(self.CourtyardLineWidth)
self.draw.SetLineTickness(self.CourtyardLineWidth)
ch_lim = B.FromMM(0.35)
self.draw.Line(-ch_lim, 0, ch_lim, 0)
self.draw.Line(0, -ch_lim, 0, ch_lim)