KiCad Pcbnew Python Scripting
Loading...
Searching...
No Matches
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.VECTOR2I( int(Hsize), int(Vsize) ))
51 pad.SetShape(shape)
52 pad.SetAttribute(pcbnew.PAD_ATTRIB_PTH)
53 pad.SetLayerSet(pad.PTHMask())
54 pad.SetDrillSize(pcbnew.VECTOR2I( int(drill), int(drill) ))
55 pad.SetOrientation( pcbnew.EDA_ANGLE( rot_degree, pcbnew.DEGREES_T ) )
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.VECTOR2I( int(drill), int(drill) ))
76 pad.SetShape(pcbnew.PAD_SHAPE_CIRCLE)
77 pad.SetAttribute(pcbnew.PAD_ATTRIB_NPTH)
78 pad.SetLayerSet(pad.UnplatedHoleMask())
79 pad.SetDrillSize(pcbnew.VECTOR2I( int(drill), int(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 shape: the shape of the pad
88 @param rot_degree: the pad rotation, in degrees
89 """
90 pad = pcbnew.PAD(self.module)
91 pad.SetSize(pcbnew.VECTOR2I( int(Hsize), int(Vsize) ) )
92 pad.SetShape(shape)
93 pad.SetAttribute(pcbnew.PAD_ATTRIB_SMD)
94 pad.SetLayerSet(pad.SMDMask())
95 pad.SetOrientation( pcbnew.EDA_ANGLE( rot_degree, pcbnew.DEGREES_T ) )
96
97 return pad
98
99 def AperturePad(self, Vsize, Hsize, shape=pcbnew.PAD_SHAPE_RECT, rot_degree=0):
100 """
101 Create a aperture pad of the given size and shape, i.e. a smd pad shape
102 on the solder paste and not on a copper
103 layer
104 @param Vsize: the vertical size of the aperture
105 @param Hsize: the horizontal size of the aperture
106 @param shape: the shape of the pad
107 @param rot_degree: the pad rotation, in degrees
108 """
109 pad = pcbnew.PAD(self.module)
110 pad.SetSize(pcbnew.VECTOR2I( int(Hsize), int(Vsize) ) )
111 pad.SetShape(shape)
112 pad.SetAttribute(pcbnew.PAD_ATTRIB_SMD)
113 pad.SetLayerSet(pad.ApertureMask())
114 pad.SetOrientation( pcbnew.EDA_ANGLE( rot_degree, pcbnew.DEGREES_T ) )
115
116 return pad
117
118 def SMTRoundPad(self, size):
119 """!
120 A round surface-mount pad. A shortcut for SMDPad()
121 @param size: pad diameter
122 """
123 pad = self.SMDPad(size, size, shape=pcbnew.PAD_SHAPE_CIRCLE)
124 return pad
125
126
128 """!
129 A class to assist in creating repetitive grids of pads
130
131 Generally, PadArrays have an internal prototypical pad, and copy this
132 for each pad in the array. They can also have a special pad for the
133 first pad, and a custom function to name the pad.
134
135 Generally, PadArray is used as a base class for more specific array
136 types.
137 """
138
139 def __init__(self, pad):
140 """!
141 @param pad: the prototypical pad
142 """
143 self.firstPadNum = 1
144 self.pinNames = None
145
146 # this pad is more of a "context", we will use it as a source of
147 # pad data, but not actually add it
148 self.pad = pad
149 self.firstPad = None
150
151 def SetPinNames(self, pinNames):
152 """!
153 Set a name for all the pins. If given, this overrides the
154 naming function.
155
156 @param pinNames: the name to use for all pins
157 """
158 self.pinNames = pinNames
159
160 def SetFirstPadType(self, firstPad):
161 """!
162 If the array has a different first pad, this is the pad that
163 is used
164 @param firstPad: the prototypical first pad
165 """
166 self.firstPad = firstPad
167
168 def SetFirstPadInArray(self, fpNum):
169 """!
170 Set the numbering for the first pad in the array
171 @param fpNum: the number for the first pad
172 """
173 self.firstPadNum = fpNum
174
175 def AddPad(self, pad):
176 """!
177 Add a pad to the array, under the same footprint as the main
178 prototype pad
179 @param pad: pad to add
180 """
181 self.pad.GetParent().Add(pad)
182
183 def GetPad(self, is_first_pad, pos):
184 """!
185 Get a pad in the array with the given position
186 @param is_first_pad: use the special first pad if there is one
187 @param pos: the pad position
188 """
189 if (self.firstPad and is_first_pad):
190 pad = self.firstPad
191 else:
192 pad = self.pad
193
194 # create a new pad with same characteristics
195 pad = pad.Duplicate()
196 pad.SetPosition(pos)
197
198 return pad
199
200 def GetName(self, *args, **kwargs):
201 """!
202 Get the pad name from the naming function, or the pre-set
203 pinNames parameter (set with SetPinNames)
204 """
205
206 if self.pinNames is None:
207 return self.NamingFunction(*args, **kwargs)
208
209 return self.pinNames
210
211 def NamingFunction(self, *args, **kwargs):
212 """!
213 Implement this as needed for each array type
214 """
215 raise NotImplementedError;
216
217
219 """!
220 A basic grid of pads
221 """
222
223 def __init__(self, pad, nx, ny, px, py, centre=pcbnew.VECTOR2I(0, 0)):
224 """!
225 @param pad: the prototypical pad of the array
226 @param nx: number of pads in x-direction
227 @param ny: number of pads in y-direction
228 @param px: pitch in x-direction
229 @param py: pitch in y-direction
230 @param centre: array centre point
231 """
232
233 try:
234 super().__init__(pad)
235 except TypeError:
236 super(PadGridArray, self).__init__(pad)
237
238 self.nx = int(nx)
239 self.ny = int(ny)
240 self.px = px
241 self.py = py
242 self.centre = centre
243
244 def AlphaNameFromNumber(self, n, aIndex=1,
245 alphabet="ABCDEFGHIJKLMNOPQRSTUVWXYZ"):
246 """!
247 Utility function to generate an alphabetical name:
248
249 eg. 1 - A, 2 - B, 26 - AA, etc
250
251 @param aIndex: index of 'A': 0 for 0 - A
252 @param n: the pad index
253 @param alphabet: set of allowable chars if not A-Z,
254 e.g. ABCDEFGHJKLMNPRTUVWY for BGA
255 """
256
257 div, mod = divmod(n - aIndex, len(alphabet))
258 alpha = alphabet[mod]
259
260 if div > 0:
261 return self.AlphaNameFromNumber(div, aIndex, alphabet) + alpha
262
263 return alpha
264
265 def NamingFunction(self, x, y):
266 """!
267 Implementation of the naming function: right to left, top-to-bottom
268
269 @param x: the pad x index
270 @param y: the pad y index
271 """
272 return self.firstPadNum + (self.nx * y + x)
273
274 #relocate the pad and add it as many times as we need
275 def AddPadsToModule(self, dc):
276 """!
277 Create the pads and add them to the module in the correct positions
278
279 @param dc: the drawing context
280 """
281
282 pin1posX = self.centre.x - self.px * (self.nx - 1) / 2
283 pin1posY = self.centre.y - self.py * (self.ny - 1) / 2
284
285 for x in range(0, self.nx):
286 posX = pin1posX + (x * self.px)
287
288 for y in range(self.ny):
289 posY = pin1posY + (self.py * y)
290 pos = dc.TransformPoint(posX, posY)
291 pad = self.GetPad(x == 0 and y == 0, pos)
292 pad.SetName(self.GetName(x,y))
293 self.AddPad(pad)
294
295
297 """!
298 A pad grid array with a fixed name, used for things like thermal
299 pads and via grids.
300 """
301
302 def NamingFunction(self, nx, ny):
303 """!
304 Simply return the firstPadNum
305 @param nx: not used
306 @param ny: not used
307 """
308 return self.firstPadNum
309
310
312 """!
313 A staggered pin array
314 """
315
316 def __init__(self, pad, pad_count, line_count, line_pitch,
317 pad_pitch, centre=pcbnew.VECTOR2I(0, 0)):
318 """!
319 @param pad: the prototypical pad
320 @param pad_count: total pad count
321 @param line_count: number of staggered lines
322 @param line_pitch: distance between lines
323 @param pad_pitch: distance between pads in a line
324 @param centre: array centre point
325 """
326 super(PadZGridArray, self).__init__(pad)
327
328 self.pad_count = int(pad_count)
329 self.line_count = int(line_count)
330 self.line_pitch = line_pitch
331 self.pad_pitch = pad_pitch
332 self.centre = centre
333
334 def NamingFunction(self, pad_pos):
335 """!
336 Naming just increased with pad index in array
337 """
338 return self.firstPadNum + pad_pos
339
340 def AddPadsToModule(self, dc):
341 """!
342 Create the pads and add them to the module in the correct positions
343
344 @param dc: the drawing context
345 """
346
347 pin1posX = self.centre.x - self.pad_pitch * (self.pad_count - 1) / 2
348 pin1posY = self.centre.y + self.line_pitch * (self.line_count - 1) / 2
349 line = 0
350
351 for padnum in range(0, self.pad_count):
352 posX = pin1posX + (padnum * self.pad_pitch)
353 posY = pin1posY - (self.line_pitch * line)
354
355 pos = dc.TransformPoint(posX, posY)
356 pad = self.GetPad(padnum == 0, pos)
357 pad.SetName(self.GetName(padnum))
358 self.AddPad(pad)
359
360 line += 1
361
362 if line >= self.line_count:
363 line = 0
364
365
367 """!
368 Shortcut cases for a single-row grid array. Can be used for
369 constructing sections of larger footprints.
370 """
371
372 def __init__(self, pad, n, pitch, isVertical,
373 centre=pcbnew.VECTOR2I(0, 0)):
374 """!
375 @param pad: the prototypical pad
376 @param n: number of pads in array
377 @param pitch: distance between pad centres
378 @param isVertical: horizontal or vertical array (can also use the
379 drawing contexts transforms for more control)
380 @param centre: array centre
381 """
382
383 if isVertical:
384 super(PadLineArray, self).__init__(pad, 1, n, 0, pitch, centre)
385 else:
386 super(PadLineArray, self).__init__(pad, n, 1, pitch, 0, centre)
387
388
390 """!
391 Circular pad array
392 """
393
394 def __init__(self, pad, n, r, angle_offset=0, centre=pcbnew.VECTOR2I(0, 0),
395 clockwise=True, padRotationEnable=False, padRotationOffset=0):
396 """!
397 @param pad: the prototypical pad
398 @param n: number of pads in array
399 @param r: the circle radius
400 @param angle_offset: angle of the first pad
401 @param centre: array centre point
402 @param clockwise: array increases in a clockwise direction
403 @param padRotationEnable: also rotate pads when placing
404 @param padRotationOffset: rotation of first pad
405 """
406
407 super(PadCircleArray, self).__init__(pad)
408
409 self.n = int(n)
410 self.r = r
411 self.angle_offset = angle_offset
412 self.centre = centre
413 self.clockwise = clockwise
414 self.padRotationEnable = padRotationEnable
415 self.padRotationOffset = padRotationOffset
416
417 def NamingFunction(self, n):
418 """!
419 Naming around the circle, CW or CCW according to the clockwise flag
420 """
421 return str(self.firstPadNum + n)
422
423 def AddPadsToModule(self, dc):
424 """!
425 Create the pads and add them to the module in the correct positions
426
427 @param dc: the drawing context
428 """
429
430 for pin in range(0, self.n):
431 angle = self.angle_offset + (360 / self.n) * pin
432
433 if not self.clockwise:
434 angle = -angle
435
436 pos_x = math.sin(angle * math.pi / 180) * self.r
437 pos_y = -math.cos(angle * math.pi / 180) * self.r
438 pos = dc.TransformPoint(pos_x, pos_y)
439 pad = self.GetPad(pin == 0, pos)
440 padAngle = self.padRotationOffset
441 if self.padRotationEnable:
442 padAngle -=angle
443 pad.SetOrientation( pcbnew.EDA_ANGLE( padAngle, pcbnew.DEGREES_T ) )
444 pad.SetName(self.GetName(pin))
445 self.AddPad(pad)
446
447
449 """!
450 Layout pads according to a custom array of [x,y] data
451 """
452
453 def __init__(self, pad, array):
454 """!
455 @param pad: the prototypical pad
456 @param array: the position data array
457 """
458 super(PadCustomArray, self).__init__(pad)
459
460 self.array = array
461
462 def NamingFunction(self, n):
463 """!
464 Simple increment along the given array
465 @param n: the pad index in the array
466 """
467 return str(self.firstPadNum + n)
468
469 def AddPadsToModule(self, dc):
470 """!
471 Create the pads and add them to the module in the correct positions
472
473 @param dc: the drawing context
474 """
475
476 for i in range(len(self.array)):
477 pos = dc.TransformPoint(self.array[i][0], self.array[i][1])
478 pad = self.GetPad(i == 0, pos)
479 pad.SetName(self.GetName(i))
480 self.AddPad(pad)
A pad grid array with a fixed name, used for things like thermal pads and via grids.
Definition: PadArray.py:296
def NamingFunction(self, nx, ny)
Simply return the firstPadNum.
Definition: PadArray.py:302
A class to assist in creating repetitive grids of pads.
Definition: PadArray.py:127
def SetFirstPadType(self, firstPad)
If the array has a different first pad, this is the pad that is used.
Definition: PadArray.py:160
def __init__(self, pad)
Definition: PadArray.py:139
def SetFirstPadInArray(self, fpNum)
Set the numbering for the first pad in the array.
Definition: PadArray.py:168
def SetPinNames(self, pinNames)
Set a name for all the pins.
Definition: PadArray.py:151
def GetPad(self, is_first_pad, pos)
Get a pad in the array with the given position.
Definition: PadArray.py:183
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:200
def NamingFunction(self, *args, **kwargs)
Implement this as needed for each array type.
Definition: PadArray.py:211
def AddPad(self, pad)
Add a pad to the array, under the same footprint as the main prototype pad.
Definition: PadArray.py:175
Circular pad array.
Definition: PadArray.py:389
def __init__(self, pad, n, r, angle_offset=0, centre=pcbnew.VECTOR2I(0, 0), clockwise=True, padRotationEnable=False, padRotationOffset=0)
Definition: PadArray.py:395
def NamingFunction(self, n)
Naming around the circle, CW or CCW according to the clockwise flag.
Definition: PadArray.py:417
def AddPadsToModule(self, dc)
Create the pads and add them to the module in the correct positions.
Definition: PadArray.py:423
Layout pads according to a custom array of [x,y] data.
Definition: PadArray.py:448
def NamingFunction(self, n)
Simple increment along the given array.
Definition: PadArray.py:462
def AddPadsToModule(self, dc)
Create the pads and add them to the module in the correct positions.
Definition: PadArray.py:469
def __init__(self, pad, array)
Definition: PadArray.py:453
A basic grid of pads.
Definition: PadArray.py:218
def AlphaNameFromNumber(self, n, aIndex=1, alphabet="ABCDEFGHIJKLMNOPQRSTUVWXYZ")
Utility function to generate an alphabetical name:
Definition: PadArray.py:245
def NamingFunction(self, x, y)
Implementation of the naming function: right to left, top-to-bottom.
Definition: PadArray.py:265
def AddPadsToModule(self, dc)
Create the pads and add them to the module in the correct positions.
Definition: PadArray.py:275
def __init__(self, pad, nx, ny, px, py, centre=pcbnew.VECTOR2I(0, 0))
Definition: PadArray.py:223
Shortcut cases for a single-row grid array.
Definition: PadArray.py:366
def __init__(self, pad, n, pitch, isVertical, centre=pcbnew.VECTOR2I(0, 0))
Definition: PadArray.py:373
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:118
def AperturePad(self, Vsize, Hsize, shape=pcbnew.PAD_SHAPE_RECT, rot_degree=0)
Definition: PadArray.py:99
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:311
def __init__(self, pad, pad_count, line_count, line_pitch, pad_pitch, centre=pcbnew.VECTOR2I(0, 0))
Definition: PadArray.py:317
def AddPadsToModule(self, dc)
Create the pads and add them to the module in the correct positions.
Definition: PadArray.py:340
def NamingFunction(self, pad_pos)
Naming just increased with pad index in array.
Definition: PadArray.py:334