Last active
July 6, 2022 16:52
-
-
Save kenkeiter/dd0a88c612eb60184d2f774b0b5e948a to your computer and use it in GitHub Desktop.
KiCAD 6 Script for arranging footprints circularly
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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