Last active
September 6, 2024 23:21
-
-
Save scottyob/5369b60413889b4fae29030f5f2e58b8 to your computer and use it in GitHub Desktop.
A script to export support items from KiCAD to JSON
This file contains hidden or 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
# Board Importer | |
# ABOUT | |
# The board has the following Edge Cuts: | |
# - Circles: These are for support screws | |
# - Polygon: This is the outside shape type | |
import pcbnew | |
import logging | |
import re | |
import pprint | |
from typing import Tuple, List | |
logger = logging.getLogger(__name__) | |
# Type alias | |
MM = int | |
X = MM | |
Y = MM | |
Width = MM | |
Height = MM | |
Rotation = int | |
# Board Dimensions | |
pcb_width = None | |
pcb_height = None | |
pcb_center_x = None | |
pcb_center_y = None | |
# Support Items to Generate | |
support_stems: List[Tuple[X, Y]] = [] | |
switches: List[Tuple[X, Y]] = [] | |
diodes: List[Tuple[X, Y, Rotation]] = [] | |
smd_cutouts: List[Tuple[X, Y, Width, Height]] = [] | |
board = pcbnew.GetBoard() | |
# Helper Functions | |
def ToFreecadCord(cord: pcbnew.VECTOR2I) -> Tuple[X, Y]: | |
""" | |
Converts the coordinate systems from KiCAD's internal measurement | |
system to mm around origin, that FreeCAD will use | |
""" | |
x, y = tuple(pcbnew.pcbIUScale.IUTomm(i) for i in cord) | |
x -= pcb_center_x | |
y -= pcb_center_y | |
return round(x, 2), -1 * round(y, 2) | |
# Populate the board dimensions | |
for drawing in board.GetDrawings(): | |
if not drawing.GetLayerName() == 'Edge.Cuts' or drawing.GetShape() != pcbnew.S_POLYGON: | |
continue | |
outline = drawing | |
box = outline.GetBoundingBox() | |
pcb_width = pcbnew.pcbIUScale.IUTomm(box.GetWidth()) | |
pcb_height = pcbnew.pcbIUScale.IUTomm(box.GetHeight()) | |
pcb_center = box.Centre() | |
pcb_center_x = pcbnew.pcbIUScale.IUTomm(box.Centre()[0]) | |
pcb_center_y = pcbnew.pcbIUScale.IUTomm(box.Centre()[1]) | |
# Generate the locations of the support stems, and the | |
for drawing in board.GetDrawings(): | |
# We're only interested in Edge cuts | |
if not drawing.GetLayerName() == 'Edge.Cuts' or drawing.GetShape() != pcbnew.S_CIRCLE: | |
continue | |
support_stems.append(ToFreecadCord(drawing.GetCenter())) | |
# Generate cutout positions for both switches, and any surface mount component we have | |
for footprint in board.GetFootprints(): | |
reference = footprint.GetReferenceAsString() | |
location = ToFreecadCord(footprint.GetPosition()) | |
if re.fullmatch(r'S\d+', reference): | |
# This is a switch | |
switches.append(location) | |
elif re.fullmatch(r'D\d+', reference): | |
x, y = location | |
diodes.append((x, y, footprint.GetOrientationDegrees())) | |
# SMD Component cutouts | |
for drawing in board.GetDrawings(): | |
if not drawing.GetLayerName() == 'User.4': | |
continue | |
x, y = ToFreecadCord(drawing.GetCenter()) | |
width = pcbnew.pcbIUScale.IUTomm(drawing.GetRectangleWidth()) | |
height = pcbnew.pcbIUScale.IUTomm(drawing.GetRectangleHeight()) | |
smd_cutouts.append((x, y, width, height)) | |
# Update the grid origin | |
board.GetDesignSettings().SetGridOrigin(pcb_center) | |
pcbnew.Refresh() | |
print("Board Supports:\n\n") | |
print(json.dumps({ | |
"width": pcb_width, | |
"height": pcb_height, | |
"support_stems": support_stems, | |
"switches": switches, | |
"diodes": diodes, | |
"smd_cutouts": smd_cutouts | |
})) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment