Skip to content

Instantly share code, notes, and snippets.

@kenkeiter
Last active July 6, 2022 16:52
Show Gist options
  • Save kenkeiter/dd0a88c612eb60184d2f774b0b5e948a to your computer and use it in GitHub Desktop.
Save kenkeiter/dd0a88c612eb60184d2f774b0b5e948a to your computer and use it in GitHub Desktop.
KiCAD 6 Script for arranging footprints circularly
import pcbnew
import math
# Based upon https://bit.ly/3agYp7f by Greg Davill (@GregDavill on Twitter)
#
# To use this with KiCAD 6.x.x:
# 1. Save this script in KiCAD's "scripting/plugins" directory as "arrange.py"
# 2. Open your PCB and refresh plugins by navigating to
# Tools > External Plugins > Refresh Plugins
# 3. Open the scripting console (Tools > Scripting Console) and execute
# something like the following:
#
# >>> import arrange
# >>> arrange.circular(['D13', 'D14', 'D15'], (100, 100), 10)
# >>> arrange.circular(arrange.ref_range('D', 1, 10), (100, 100), 10)
def ref_range(prefix, start, end):
"""
Generates a sequence of reference designators.
Args:
prefix (str): the prefix of the reference designator (for example, 'D')
start (int): the start of the range
end (int): the end of the range (including this number)
Example:
>>> rng = ref_range('D', 1, 5)
>>> list(rng)
['D1', 'D2', 'D3', 'D4', 'D5]
"""
for idx in range(start, end+1):
yield prefix + str(idx)
def circular(refs, center, radius, rotation_offset_deg=0, radius_offset_deg=0):
"""
Place a set of footprints (as identified by a list of their reference
designators `refs`) around a `center` point at a given `radius`, with
optional part rotational offsets and a radius offset that shifts all
components a set number of degrees of rotation.
Args:
refs (iterable): an iterable (list, tuple, etc.) containing strings
identifying the parts to be rotated by their reference designators
(i.e. `['D1', 'D2', 'D3']`)
center (tuple): a tuple containing two numbers (x, y) locating the
center of the circle
radius (float): a number describing the distance from `center` at which
parts will be placed
roation_offset_deg (float): [optional] a fixed number of degrees by
which to rotate each part in addition to the automatic rotation
of the part to orient it toward the center of the circle
radius_offset_deg (float): [optional] a fixed number of degrees by
which all parts rotations' will be shifted around the radius of
the circle
"""
pcb = pcbnew.GetBoard()
ref_count = len(refs)
for i, ref in enumerate(refs):
part = pcb.FindFootprintByReference(ref)
rad = (2 * math.pi) * ((i + 1) / ref_count) + math.radians(radius_offset_deg)
new_pos = pcbnew.VECTOR2I(
pcbnew.FromMM(center[0] + radius*math.cos(rad)),
pcbnew.FromMM(center[1] + radius*math.sin(rad)))
part.SetPosition(new_pos)
part.SetOrientationDegrees(
(((i + 1) / ref_count) * -360) - rotation_offset_deg - radius_offset_deg)
# refresh the layout after performing the above operations
pcbnew.Refresh()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment