KiCad Pcbnew Python Scripting
PadArray.py
Go to the documentation of this file.
1 # PadArray.py
2 #
3 # Copyright 2014 john <john@johndev>
4 #
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18 # MA 02110-1301, USA.
19 #
20 #
21 
22 from __future__ import division
23 
24 import math
25 import pcbnew
26 
28  """!
29  Useful construction functions for common types of pads, providing
30  sensible defaults for common pads.
31  """
32 
33  def __init__(self, module):
34  """!
35  @param module: the module the pads will be part of
36  """
37  self.module = module
38 
39  def THPad(self, Vsize, Hsize, drill, shape=pcbnew.PAD_SHAPE_OVAL,
40  rot_degree = 0):
41  """!
42  A basic through-hole pad of the given size and shape
43  @param Vsize: the vertical size of the pad
44  @param Hsize: the horizontal size of the pad
45  @param drill: the drill diameter
46  @param shape: the shape of the pad
47  @param rot_degree: the pad rotation, in degrees
48  """
49  pad = pcbnew.D_PAD(self.module)
50  pad.SetSize(pcbnew.wxSize(Hsize, Vsize))
51  pad.SetShape(shape)
52  pad.SetAttribute(pcbnew.PAD_ATTRIB_STANDARD)
53  pad.SetLayerSet(pad.StandardMask())
54  pad.SetDrillSize(pcbnew.wxSize(drill, drill))
55  pad.SetOrientation(rot_degree*10) # rotation is in 0.1 degrees
56 
57  return pad
58 
59  def THRoundPad(self, size, drill):
60  """!
61  A round though-hole pad. A shortcut for THPad()
62  @param size: pad diameter
63  @param drill: drill diameter
64  """
65  pad = self.THPad(size, size, drill, shape=pcbnew.PAD_SHAPE_CIRCLE)
66  return pad
67 
68  def NPTHRoundPad(self, drill):
69  """!
70  A round non-plated though hole (NPTH)
71 
72  @param drill: the drill diameter (equals the NPTH diameter)
73  """
74  pad = pcbnew.D_PAD(self.module)
75  pad.SetSize(pcbnew.wxSize(drill, drill))
76  pad.SetShape(pcbnew.PAD_SHAPE_CIRCLE)
77  pad.SetAttribute(pcbnew.PAD_ATTRIB_HOLE_NOT_PLATED)
78  pad.SetLayerSet(pad.UnplatedHoleMask())
79  pad.SetDrillSize(pcbnew.wxSize(drill, drill))
80  return pad
81 
82  def SMDPad(self, Vsize, Hsize, shape=pcbnew.PAD_SHAPE_RECT, rot_degree=0):
83  """
84  Create a surface-mount pad of the given size and shape
85  @param Vsize: the vertical size of the pad
86  @param Hsize: the horizontal size of the pad
87  @param drill: the drill diameter
88  @param shape: the shape of the pad
89  @param rot_degree: the pad rotation, in degrees
90  """
91  pad = pcbnew.D_PAD(self.module)
92  pad.SetSize(pcbnew.wxSize(Hsize, Vsize))
93  pad.SetShape(shape)
94  pad.SetAttribute(pcbnew.PAD_ATTRIB_SMD)
95  pad.SetLayerSet(pad.SMDMask())
96  pad.SetOrientation(rot_degree*10) # rotation is in 0.1 degrees
97 
98  return pad
99 
100  def SMTRoundPad(self, size):
101  """!
102  A round surface-mount pad. A shortcut for SMDPad()
103  @param size: pad diameter
104  """
105  pad = self.SMDPad(size, size, shape=pcbnew.PAD_SHAPE_CIRCLE)
106  return pad
107 
108 
110  """!
111  A class to assist in creating repetitive grids of pads
112 
113  Generally, PadArrays have an internal prototypical pad, and copy this
114  for each pad in the array. They can also have a special pad for the
115  first pad, and a custom function to name the pad.
116 
117  Generally, PadArray is used as a base class for more specific array
118  types.
119  """
120 
121  def __init__(self, pad):
122  """!
123  @param pad: the prototypical pad
124  """
125  self.firstPadNum = 1
126  self.pinNames = None
127 
128  # this pad is more of a "context", we will use it as a source of
129  # pad data, but not actually add it
130  self.pad = pad
131  self.firstPad = None
132 
133  def SetPinNames(self, pinNames):
134  """!
135  Set a name for all the pins. If given, this overrides the
136  naming function.
137 
138  @param pinNames: the name to use for all pins
139  """
140  self.pinNames = pinNames
141 
142  def SetFirstPadType(self, firstPad):
143  """!
144  If the array has a different first pad, this is the pad that
145  is used
146  @param firstPad: the prototypical first pad
147  """
148  self.firstPad = firstPad
149 
150  def SetFirstPadInArray(self, fpNum):
151  """!
152  Set the numbering for the first pad in the array
153  @param fpNum: the number for the first pad
154  """
155  self.firstPadNum = fpNum
156 
157  def AddPad(self, pad):
158  """!
159  Add a pad to the array, under the same moodule as the main
160  prototype pad
161  @param pad: pad to add
162  """
163  self.pad.GetParent().Add(pad)
164 
165  def GetPad(self, is_first_pad, pos):
166  """!
167  Get a pad in the array with the given position
168  @param is_first_pad: use the special first pad if there is one
169  @param pos: the pad position
170  """
171  if (self.firstPad and is_first_pad):
172  pad = self.firstPad
173  else:
174  pad = self.pad
175 
176  # create a new pad with same characteristics
177  pad = pad.Duplicate()
178  pad.SetPos0(pos)
179  pad.SetPosition(pos)
180 
181  return pad
182 
183  def GetName(self, *args, **kwargs):
184  """!
185  Get the pad name from the naming function, or the pre-set
186  pinNames parameter (set with SetPinNames)
187  """
188 
189  if self.pinNames is None:
190  return self.NamingFunction(*args, **kwargs)
191 
192  return self.pinNames
193 
194  def NamingFunction(self, *args, **kwargs):
195  """!
196  Implement this as needed for each array type
197  """
198  raise NotImplementedError;
199 
200 
202  """!
203  A basic grid of pads
204  """
205 
206  def __init__(self, pad, nx, ny, px, py, centre=pcbnew.wxPoint(0, 0)):
207  """!
208  @param pad: the prototypical pad of the array
209  @param nx: number of pads in x-direction
210  @param ny: number of pads in y-direction
211  @param px: pitch in x-direction
212  @param py: pitch in y-direction
213  @param centre: array centre point
214  """
215  super(PadGridArray, self).__init__(pad)
216 
217  self.nx = int(nx)
218  self.ny = int(ny)
219  self.px = px
220  self.py = py
221  self.centre = centre
222 
223  def AlphaNameFromNumber(self, n, aIndex=1,
224  alphabet="ABCDEFGHIJKLMNOPQRSTUVWXYZ"):
225  """!
226  Utility function to generate an alphabetical name:
227 
228  eg. 1 - A, 2 - B, 26 - AA, etc
229 
230  @param aIndex: index of 'A': 0 for 0 - A
231  @param n: the pad index
232  @param alphabet: set of allowable chars if not A-Z,
233  e.g. ABCDEFGHJKLMNPRTUVWY for BGA
234  """
235 
236  div, mod = divmod(n - aIndex, len(alphabet))
237  alpha = alphabet[mod]
238 
239  if div > 0:
240  return self.AlphaNameFromNumber(div, aIndex, alphabet) + alpha
241 
242  return alpha
243 
244  def NamingFunction(self, x, y):
245  """!
246  Implementation of the naming function: right to left, top-to-bottom
247 
248  @param x: the pad x index
249  @param y: the pad y index
250  """
251  return self.firstPadNum + (self.nx * y + x)
252 
253  #relocate the pad and add it as many times as we need
254  def AddPadsToModule(self, dc):
255  """!
256  Create the pads and add them to the module in the correct positions
257 
258  @param dc: the drawing context
259  """
260 
261  pin1posX = self.centre.x - self.px * (self.nx - 1) / 2
262  pin1posY = self.centre.y - self.py * (self.ny - 1) / 2
263 
264  for x in range(0, self.nx):
265  posX = pin1posX + (x * self.px)
266 
267  for y in range(self.ny):
268  posY = pin1posY + (self.py * y)
269  pos = dc.TransformPoint(posX, posY)
270  pad = self.GetPad(x == 0 and y == 0, pos)
271  pad.SetName(self.GetName(x,y))
272  self.AddPad(pad)
273 
274 
276  """!
277  A pad grid array with a fixed name, used for things like thermal
278  pads and via grids.
279  """
280 
281  def NamingFunction(self, nx, ny):
282  """!
283  Simply return the firstPadNum
284  @param nx: not used
285  @param ny: not used
286  """
287  return self.firstPadNum
288 
289 
291  """!
292  A staggered pin array
293  """
294 
295  def __init__(self, pad, pad_count, line_count, line_pitch,
296  pad_pitch, centre=pcbnew.wxPoint(0, 0)):
297  """!
298  @param pad: the prototypical pad
299  @param pad_count: total pad count
300  @param line_count: number of staggered lines
301  @param line_pitch: distance between lines
302  @param pad_pitch: distance between pads in a line
303  @param centre: array centre point
304  """
305  super(PadZGridArray, self).__init__(pad)
306 
307  self.pad_count = int(pad_count)
308  self.line_count = int(line_count)
309  self.line_pitch = line_pitch
310  self.pad_pitch = pad_pitch
311  self.centre = centre
312 
313  def NamingFunction(self, pad_pos):
314  """!
315  Naming just increased with pad index in array
316  """
317  return self.firstPadNum + pad_pos
318 
319  def AddPadsToModule(self, dc):
320  """!
321  Create the pads and add them to the module in the correct positions
322 
323  @param dc: the drawing context
324  """
325 
326  pin1posX = self.centre.x - self.pad_pitch * (self.pad_count - 1) / 2
327  pin1posY = self.centre.y + self.line_pitch * (self.line_count - 1) / 2
328  line = 0
329 
330  for padnum in range(0, self.pad_count):
331  posX = pin1posX + (padnum * self.pad_pitch)
332  posY = pin1posY - (self.line_pitch * line)
333 
334  pos = dc.TransformPoint(posX, posY)
335  pad = self.GetPad(padnum == 0, pos)
336  pad.SetName(self.GetName(padnum))
337  self.AddPad(pad)
338 
339  line += 1
340 
341  if line >= self.line_count:
342  line = 0
343 
344 
346  """!
347  Shortcut cases for a single-row grid array. Can be used for
348  constructing sections of larger footprints.
349  """
350 
351  def __init__(self, pad, n, pitch, isVertical,
352  centre=pcbnew.wxPoint(0, 0)):
353  """!
354  @param pad: the prototypical pad
355  @param n: number of pads in array
356  @param pitch: distance between pad centres
357  @param isVertical: horizontal or vertical array (can also use the
358  drawing contexts transforms for more control)
359  @param centre: array centre
360  """
361 
362  if isVertical:
363  super(PadLineArray, self).__init__(pad, 1, n, 0, pitch, centre)
364  else:
365  super(PadLineArray, self).__init__(pad, n, 1, pitch, 0, centre)
366 
367 
369  """!
370  Circular pad array
371  """
372 
373  def __init__(self, pad, n, r, angle_offset=0, centre=pcbnew.wxPoint(0, 0),
374  clockwise=True, padRotationEnable=False, padRotationOffset=0):
375  """!
376  @param pad: the prototypical pad
377  @param n: number of pads in array
378  @param r: the circle radius
379  @param angle_offset: angle of the first pad
380  @param centre: array centre point
381  @param clockwise: array increases in a clockwise direction
382  @param padRotationEnable: also rotate pads when placing
383  @param padRotationOffset: rotation of first pad
384  """
385 
386  super(PadCircleArray, self).__init__(pad)
387 
388  self.n = int(n)
389  self.r = r
390  self.angle_offset = angle_offset
391  self.centre = centre
392  self.clockwise = clockwise
393  self.padRotationEnable = padRotationEnable
394  self.padRotationOffset = padRotationOffset
395 
396  def NamingFunction(self, n):
397  """!
398  Naming around the circle, CW or CCW according to the clockwise flag
399  """
400  return str(self.firstPadNum + n)
401 
402  def AddPadsToModule(self, dc):
403  """!
404  Create the pads and add them to the module in the correct positions
405 
406  @param dc: the drawing context
407  """
408 
409  for pin in range(0, self.n):
410  angle = self.angle_offset + (360 / self.n) * pin
411 
412  if not self.clockwise:
413  angle = -angle
414 
415  pos_x = math.sin(angle * math.pi / 180) * self.r
416  pos_y = -math.cos(angle * math.pi / 180) * self.r
417  pos = dc.TransformPoint(pos_x, pos_y)
418  pad = self.GetPad(pin == 0, pos)
419  padAngle = self.padRotationOffset
420  if self.padRotationEnable:
421  padAngle -=angle
422  pad.SetOrientation(padAngle*10)
423  pad.SetName(self.GetName(pin))
424  self.AddPad(pad)
425 
426 
428  """!
429  Layout pads according to a custom array of [x,y] data
430  """
431 
432  def __init__(self, pad, array):
433  """!
434  @param pad: the prototypical pad
435  @param array: the position data array
436  """
437  super(PadCustomArray, self).__init__(pad)
438 
439  self.array = array
440 
441  def NamingFunction(self, n):
442  """!
443  Simple increment along the given array
444  @param n: the pad index in the array
445  """
446  return str(self.firstPadNum + n)
447 
448  def AddPadsToModule(self, dc):
449  """!
450  Create the pads and add them to the module in the correct positions
451 
452  @param dc: the drawing context
453  """
454 
455  for i in range(len(self.array)):
456  pos = dc.TransformPoint(self.array[i][0], self.array[i][1])
457  pad = self.GetPad(i == 0, pos)
458  pad.SetName(self.GetName(i))
459  self.AddPad(pad)
def NamingFunction(self, n)
Simple increment along the given array.
Definition: PadArray.py:441
def THRoundPad(self, size, drill)
A round though-hole pad.
Definition: PadArray.py:59
A staggered pin array.
Definition: PadArray.py:290
def GetPad(self, is_first_pad, pos)
Get a pad in the array with the given position.
Definition: PadArray.py:165
def __init__(self, module)
Definition: PadArray.py:33
def AddPadsToModule(self, dc)
Create the pads and add them to the module in the correct positions.
Definition: PadArray.py:448
def NamingFunction(self, n)
Naming around the circle, CW or CCW according to the clockwise flag.
Definition: PadArray.py:396
def NPTHRoundPad(self, drill)
A round non-plated though hole (NPTH)
Definition: PadArray.py:68
def SMDPad(self, Vsize, Hsize, shape=pcbnew.PAD_SHAPE_RECT, rot_degree=0)
Definition: PadArray.py:82
def SetFirstPadType(self, firstPad)
If the array has a different first pad, this is the pad that is used.
Definition: PadArray.py:142
def SetPinNames(self, pinNames)
Set a name for all the pins.
Definition: PadArray.py:133
def AddPadsToModule(self, dc)
Create the pads and add them to the module in the correct positions.
Definition: PadArray.py:402
def GetName(self, args, kwargs)
Get the pad name from the naming function, or the pre-set pinNames parameter (set with SetPinNames) ...
Definition: PadArray.py:183
def AddPad(self, pad)
Add a pad to the array, under the same moodule as the main prototype pad.
Definition: PadArray.py:157
def __init__(self, pad, array)
Definition: PadArray.py:432
Shortcut cases for a single-row grid array.
Definition: PadArray.py:345
def AlphaNameFromNumber(self, n, aIndex=1, alphabet="ABCDEFGHIJKLMNOPQRSTUVWXYZ")
Utility function to generate an alphabetical name:
Definition: PadArray.py:224
Layout pads according to a custom array of [x,y] data.
Definition: PadArray.py:427
def AddPadsToModule(self, dc)
Create the pads and add them to the module in the correct positions.
Definition: PadArray.py:319
def NamingFunction(self, x, y)
Implementation of the naming function: right to left, top-to-bottom.
Definition: PadArray.py:244
A basic grid of pads.
Definition: PadArray.py:201
def __init__(self, pad, nx, ny, px, py, centre=pcbnew.wxPoint(0, 0))
Definition: PadArray.py:206
def __init__(self, pad, n, pitch, isVertical, centre=pcbnew.wxPoint(0, 0))
Definition: PadArray.py:352
A pad grid array with a fixed name, used for things like thermal pads and via grids.
Definition: PadArray.py:275
def SMTRoundPad(self, size)
A round surface-mount pad.
Definition: PadArray.py:100
def __init__(self, pad, n, r, angle_offset=0, centre=pcbnew.wxPoint(0, 0), clockwise=True, padRotationEnable=False, padRotationOffset=0)
Definition: PadArray.py:374
def AddPadsToModule(self, dc)
Create the pads and add them to the module in the correct positions.
Definition: PadArray.py:254
Useful construction functions for common types of pads, providing sensible defaults for common pads...
Definition: PadArray.py:27
def __init__(self, pad, pad_count, line_count, line_pitch, pad_pitch, centre=pcbnew.wxPoint(0, 0))
Definition: PadArray.py:296
def SetFirstPadInArray(self, fpNum)
Set the numbering for the first pad in the array.
Definition: PadArray.py:150
Circular pad array.
Definition: PadArray.py:368
def NamingFunction(self, args, kwargs)
Implement this as needed for each array type.
Definition: PadArray.py:194
A class to assist in creating repetitive grids of pads.
Definition: PadArray.py:109
def __init__(self, pad)
Definition: PadArray.py:121
def NamingFunction(self, pad_pos)
Naming just increased with pad index in array.
Definition: PadArray.py:313
def THPad(self, Vsize, Hsize, drill, shape=pcbnew.PAD_SHAPE_OVAL, rot_degree=0)
A basic through-hole pad of the given size and shape.
Definition: PadArray.py:40
def NamingFunction(self, nx, ny)
Simply return the firstPadNum.
Definition: PadArray.py:281