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
22from __future__ import division
23
24import math
25import 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.PAD(self.module)
50 pad.SetSize(pcbnew.wxSize(Hsize, Vsize))
51 pad.SetShape(shape)
52 pad.SetAttribute(pcbnew.PAD_ATTRIB_PTH)
53 pad.SetLayerSet(pad.PTHMask())
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.PAD(self.module)
75 pad.SetSize(pcbnew.wxSize(drill, drill))
76 pad.SetShape(pcbnew.PAD_SHAPE_CIRCLE)
77 pad.SetAttribute(pcbnew.PAD_ATTRIB_NPTH)
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.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
216 try:
217 super().__init__(pad)
218 except TypeError:
219 super(PadGridArray, self).__init__(pad)
220
221 self.nx = int(nx)
222 self.ny = int(ny)
223 self.px = px
224 self.py = py
225 self.centre = centre
226
227 def AlphaNameFromNumber(self, n, aIndex=1,
228 alphabet="ABCDEFGHIJKLMNOPQRSTUVWXYZ"):
229 """!
230 Utility function to generate an alphabetical name:
231
232 eg. 1 - A, 2 - B, 26 - AA, etc
233
234 @param aIndex: index of 'A': 0 for 0 - A
235 @param n: the pad index
236 @param alphabet: set of allowable chars if not A-Z,
237 e.g. ABCDEFGHJKLMNPRTUVWY for BGA
238 """
239
240 div, mod = divmod(n - aIndex, len(alphabet))
241 alpha = alphabet[mod]
242
243 if div > 0:
244 return self.AlphaNameFromNumber(div, aIndex, alphabet) + alpha
245
246 return alpha
247
248 def NamingFunction(self, x, y):
249 """!
250 Implementation of the naming function: right to left, top-to-bottom
251
252 @param x: the pad x index
253 @param y: the pad y index
254 """
255 return self.firstPadNum + (self.nx * y + x)
256
257 #relocate the pad and add it as many times as we need
258 def AddPadsToModule(self, dc):
259 """!
260 Create the pads and add them to the module in the correct positions
261
262 @param dc: the drawing context
263 """
264
265 pin1posX = self.centre.x - self.px * (self.nx - 1) / 2
266 pin1posY = self.centre.y - self.py * (self.ny - 1) / 2
267
268 for x in range(0, self.nx):
269 posX = pin1posX + (x * self.px)
270
271 for y in range(self.ny):
272 posY = pin1posY + (self.py * y)
273 pos = dc.TransformPoint(posX, posY)
274 pad = self.GetPad(x == 0 and y == 0, pos)
275 pad.SetName(self.GetName(x,y))
276 self.AddPad(pad)
277
278
280 """!
281 A pad grid array with a fixed name, used for things like thermal
282 pads and via grids.
283 """
284
285 def NamingFunction(self, nx, ny):
286 """!
287 Simply return the firstPadNum
288 @param nx: not used
289 @param ny: not used
290 """
291 return self.firstPadNum
292
293
295 """!
296 A staggered pin array
297 """
298
299 def __init__(self, pad, pad_count, line_count, line_pitch,
300 pad_pitch, centre=pcbnew.wxPoint(0, 0)):
301 """!
302 @param pad: the prototypical pad
303 @param pad_count: total pad count
304 @param line_count: number of staggered lines
305 @param line_pitch: distance between lines
306 @param pad_pitch: distance between pads in a line
307 @param centre: array centre point
308 """
309 super(PadZGridArray, self).__init__(pad)
310
311 self.pad_count = int(pad_count)
312 self.line_count = int(line_count)
313 self.line_pitch = line_pitch
314 self.pad_pitch = pad_pitch
315 self.centre = centre
316
317 def NamingFunction(self, pad_pos):
318 """!
319 Naming just increased with pad index in array
320 """
321 return self.firstPadNum + pad_pos
322
323 def AddPadsToModule(self, dc):
324 """!
325 Create the pads and add them to the module in the correct positions
326
327 @param dc: the drawing context
328 """
329
330 pin1posX = self.centre.x - self.pad_pitch * (self.pad_count - 1) / 2
331 pin1posY = self.centre.y + self.line_pitch * (self.line_count - 1) / 2
332 line = 0
333
334 for padnum in range(0, self.pad_count):
335 posX = pin1posX + (padnum * self.pad_pitch)
336 posY = pin1posY - (self.line_pitch * line)
337
338 pos = dc.TransformPoint(posX, posY)
339 pad = self.GetPad(padnum == 0, pos)
340 pad.SetName(self.GetName(padnum))
341 self.AddPad(pad)
342
343 line += 1
344
345 if line >= self.line_count:
346 line = 0
347
348
350 """!
351 Shortcut cases for a single-row grid array. Can be used for
352 constructing sections of larger footprints.
353 """
354
355 def __init__(self, pad, n, pitch, isVertical,
356 centre=pcbnew.wxPoint(0, 0)):
357 """!
358 @param pad: the prototypical pad
359 @param n: number of pads in array
360 @param pitch: distance between pad centres
361 @param isVertical: horizontal or vertical array (can also use the
362 drawing contexts transforms for more control)
363 @param centre: array centre
364 """
365
366 if isVertical:
367 super(PadLineArray, self).__init__(pad, 1, n, 0, pitch, centre)
368 else:
369 super(PadLineArray, self).__init__(pad, n, 1, pitch, 0, centre)
370
371
373 """!
374 Circular pad array
375 """
376
377 def __init__(self, pad, n, r, angle_offset=0, centre=pcbnew.wxPoint(0, 0),
378 clockwise=True, padRotationEnable=False, padRotationOffset=0):
379 """!
380 @param pad: the prototypical pad
381 @param n: number of pads in array
382 @param r: the circle radius
383 @param angle_offset: angle of the first pad
384 @param centre: array centre point
385 @param clockwise: array increases in a clockwise direction
386 @param padRotationEnable: also rotate pads when placing
387 @param padRotationOffset: rotation of first pad
388 """
389
390 super(PadCircleArray, self).__init__(pad)
391
392 self.n = int(n)
393 self.r = r
394 self.angle_offset = angle_offset
395 self.centre = centre
396 self.clockwise = clockwise
397 self.padRotationEnable = padRotationEnable
398 self.padRotationOffset = padRotationOffset
399
400 def NamingFunction(self, n):
401 """!
402 Naming around the circle, CW or CCW according to the clockwise flag
403 """
404 return str(self.firstPadNum + n)
405
406 def AddPadsToModule(self, dc):
407 """!
408 Create the pads and add them to the module in the correct positions
409
410 @param dc: the drawing context
411 """
412
413 for pin in range(0, self.n):
414 angle = self.angle_offset + (360 / self.n) * pin
415
416 if not self.clockwise:
417 angle = -angle
418
419 pos_x = math.sin(angle * math.pi / 180) * self.r
420 pos_y = -math.cos(angle * math.pi / 180) * self.r
421 pos = dc.TransformPoint(pos_x, pos_y)
422 pad = self.GetPad(pin == 0, pos)
423 padAngle = self.padRotationOffset
424 if self.padRotationEnable:
425 padAngle -=angle
426 pad.SetOrientation(padAngle*10)
427 pad.SetName(self.GetName(pin))
428 self.AddPad(pad)
429
430
432 """!
433 Layout pads according to a custom array of [x,y] data
434 """
435
436 def __init__(self, pad, array):
437 """!
438 @param pad: the prototypical pad
439 @param array: the position data array
440 """
441 super(PadCustomArray, self).__init__(pad)
442
443 self.array = array
444
445 def NamingFunction(self, n):
446 """!
447 Simple increment along the given array
448 @param n: the pad index in the array
449 """
450 return str(self.firstPadNum + n)
451
452 def AddPadsToModule(self, dc):
453 """!
454 Create the pads and add them to the module in the correct positions
455
456 @param dc: the drawing context
457 """
458
459 for i in range(len(self.array)):
460 pos = dc.TransformPoint(self.array[i][0], self.array[i][1])
461 pad = self.GetPad(i == 0, pos)
462 pad.SetName(self.GetName(i))
463 self.AddPad(pad)
A pad grid array with a fixed name, used for things like thermal pads and via grids.
Definition: PadArray.py:279
def NamingFunction(self, nx, ny)
Simply return the firstPadNum.
Definition: PadArray.py:285
A class to assist in creating repetitive grids of pads.
Definition: PadArray.py:109
def SetFirstPadType(self, firstPad)
If the array has a different first pad, this is the pad that is used.
Definition: PadArray.py:142
def __init__(self, pad)
Definition: PadArray.py:121
def SetFirstPadInArray(self, fpNum)
Set the numbering for the first pad in the array.
Definition: PadArray.py:150
def SetPinNames(self, pinNames)
Set a name for all the pins.
Definition: PadArray.py:133
def GetPad(self, is_first_pad, pos)
Get a pad in the array with the given position.
Definition: PadArray.py:165
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 NamingFunction(self, *args, **kwargs)
Implement this as needed for each array type.
Definition: PadArray.py:194
def AddPad(self, pad)
Add a pad to the array, under the same moodule as the main prototype pad.
Definition: PadArray.py:157
Circular pad array.
Definition: PadArray.py:372
def NamingFunction(self, n)
Naming around the circle, CW or CCW according to the clockwise flag.
Definition: PadArray.py:400
def __init__(self, pad, n, r, angle_offset=0, centre=pcbnew.wxPoint(0, 0), clockwise=True, padRotationEnable=False, padRotationOffset=0)
Definition: PadArray.py:378
def AddPadsToModule(self, dc)
Create the pads and add them to the module in the correct positions.
Definition: PadArray.py:406
Layout pads according to a custom array of [x,y] data.
Definition: PadArray.py:431
def NamingFunction(self, n)
Simple increment along the given array.
Definition: PadArray.py:445
def AddPadsToModule(self, dc)
Create the pads and add them to the module in the correct positions.
Definition: PadArray.py:452
def __init__(self, pad, array)
Definition: PadArray.py:436
A basic grid of pads.
Definition: PadArray.py:201
def AlphaNameFromNumber(self, n, aIndex=1, alphabet="ABCDEFGHIJKLMNOPQRSTUVWXYZ")
Utility function to generate an alphabetical name:
Definition: PadArray.py:228
def NamingFunction(self, x, y)
Implementation of the naming function: right to left, top-to-bottom.
Definition: PadArray.py:248
def AddPadsToModule(self, dc)
Create the pads and add them to the module in the correct positions.
Definition: PadArray.py:258
def __init__(self, pad, nx, ny, px, py, centre=pcbnew.wxPoint(0, 0))
Definition: PadArray.py:206
Shortcut cases for a single-row grid array.
Definition: PadArray.py:349
def __init__(self, pad, n, pitch, isVertical, centre=pcbnew.wxPoint(0, 0))
Definition: PadArray.py:356
Useful construction functions for common types of pads, providing sensible defaults for common pads.
Definition: PadArray.py:27
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 __init__(self, module)
Definition: PadArray.py:33
def THRoundPad(self, size, drill)
A round though-hole pad.
Definition: PadArray.py:59
def SMTRoundPad(self, size)
A round surface-mount pad.
Definition: PadArray.py:100
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
A staggered pin array.
Definition: PadArray.py:294
def AddPadsToModule(self, dc)
Create the pads and add them to the module in the correct positions.
Definition: PadArray.py:323
def NamingFunction(self, pad_pos)
Naming just increased with pad index in array.
Definition: PadArray.py:317
def __init__(self, pad, pad_count, line_count, line_pitch, pad_pitch, centre=pcbnew.wxPoint(0, 0))
Definition: PadArray.py:300