Skip to content

Instantly share code, notes, and snippets.

@scottyob
Last active September 6, 2024 23:21
Show Gist options
  • Save scottyob/5369b60413889b4fae29030f5f2e58b8 to your computer and use it in GitHub Desktop.
Save scottyob/5369b60413889b4fae29030f5f2e58b8 to your computer and use it in GitHub Desktop.
A script to export support items from KiCAD to JSON
# 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