Files
kicad-ci/.scripts/pre_panel.py

188 lines
6.3 KiB
Python

import json
import sys
import shutil
from kikit.panelize import Origin,getOriginCoord
from kikit.common import findBoardBoundingBox
from pcbnewTransition.pcbnew import LoadBoard
PCB_DIV_MM = 1000000
proj_file = sys.argv[1]
pcb_file = sys.argv[2]
panel_file = sys.argv[3]
def str_mm_to_float(input: str) -> float:
input = input.lower()
# Panic, should all be in mm for sanity's sake
if "mm" not in input:
print(input, "not in mm")
exit(1)
return float(input.replace("mm", ""))
def float_to_str_mm(input: float, n: int=0) -> str:
return "{:.2f}".format(input).zfill(n+3)+"mm"
def float_to_deg(input: float, n: int=0) -> str:
return "{:.2f}".format(input).zfill(n+3)+"deg"
class Text:
def __init__(self, text: str, anchor: str, offset: tuple[float, float], rot: float, size: tuple[float, float, float] = (1.0, 1.0, 0.16), just: tuple[str, str] = ('center', 'center')):
self.text = text
self.anchor = anchor
self.hoff = float_to_str_mm(offset[0])
self.voff = float_to_str_mm(offset[1])
self.rot = str(rot)+"deg"
self.width = float_to_str_mm(size[0])
self.height = float_to_str_mm(size[1])
self.thickness = float_to_str_mm(size[2])
self.hjust = just[0]
self.vjust = just[1]
def to_dict(self, n: int) -> dict:
if n == 0:
str_n = ''
else:
str_n = str(n + 1)
return {
"text" + str_n:
{
"type": "simple",
"text": self.text,
"anchor": self.anchor,
"hoffset": self.hoff,
"voffset": self.voff,
"orientation": self.rot,
"width": self.width,
"height": self.height,
"hjustify": self.hjust,
"vjustify": self.vjust,
"thickness": self.thickness,
}
}
class Frame:
def __init__(self, ftype: str, width: str, spacing: str):
self.ftype = ftype.lower()
self.width = str_mm_to_float(width)
self.spacing = str_mm_to_float(spacing)
if "frame" in self.ftype:
self.extra_d = [(self.width + self.spacing)*2, (self.width + self.spacing)*2]
elif "tb" in self.ftype:
self.extra_d = [0, (self.width + self.spacing)*2]
else:
self.extra_d = [(self.width + self.spacing)*2, 0]
class Board:
def __init__(self, fids: list[tuple[float, float]], rot: float, dims: tuple[float, float]):
fid_list = []
for f in fids:
fid_list.append("(" + float_to_str_mm(f[0]) + ", " + float_to_str_mm(f[1]) + ")")
self.fids = ",".join(fid_list)
self.rot = rot
self.dims = dims
class Panel:
def __init__(self, spacing: str, grid: (int, int), frame: Frame, board: Board):
self.spacing = str_mm_to_float(spacing)
self.grid = grid
self.gaps = (grid[0] - 1, grid[1] - 1)
self.frame = frame
self.text = None
self.text2 = None
self.text3 = None
self.text4 = None
self.dims = [self.gaps[i]*self.spacing + self.grid[i]*board.dims[i] + frame.extra_d[i] for i in range(0,2)]
arrow_off = [frame.spacing + frame.width, frame.width]
text_off = [arrow_off[0] + 2, frame.width/2]
if "frame" in frame.ftype or "tb" in frame.ftype:
txt_loc = ('mt', 'bl')
txt_off = ((0, text_off[1]), (text_off[0], -text_off[1]))
txt_just = (('center', 'center'), ('left', 'center'))
txt_rot = 0
else:
txt_loc = ('ml', 'br')
txt_off = ((text_off[1], 0), (text_off[1], text_off[0]))
txt_just = (('center', 'center'), ('center', 'center'))
txt_rot = 90
self.text = Text("{boardTitle}-{boardRevision}", txt_loc[0], txt_off[0], txt_rot, just=txt_just[0]).to_dict(0)
spacer = " "
txt =\
"PNL (x,y) : (" + "x: " +float_to_str_mm(self.dims[0],4) + ", " + float_to_str_mm(self.dims[1],4) + ")\n" +\
"BRD (x,y),r: (" + float_to_str_mm(board.dims[0],4) + ", " + float_to_str_mm(board.dims[1],4) + "), " +\
float_to_deg(board.rot, 3) + "\n" +\
"FIDS (x,y) : " + board.fids
self.text2 = Text(txt, txt_loc[1], txt_off[1], txt_rot, just=txt_just[1]).to_dict(1)
if "frame" in self.frame.ftype:
self.text3 = Text("ORIGY ->", "bl", (arrow_off[1], -arrow_off[0]), 0, just=("right", "center")).to_dict(2)
self.text4 = Text("ORIGX ->", "bl", (arrow_off[0], -arrow_off[1]), 90, just=("right", "center")).to_dict(3)
print("Starting pre_panel script")
board = LoadBoard(pcb_file)
sourceArea = findBoardBoundingBox(board)
# bottomOrig = [(a - b)/10**6 for a,b in zip(*[list(getOriginCoord(o, sourceArea)) for o in [Origin.BottomRight, Origin.BottomLeft]])]
# print("bottom Orig: ", bottomOrig)
fids = []
for foot in board.Footprints():
if "FID" in foot.GetReference():
cent = foot.GetBoundingBox().GetCenter()
fids.append(tuple([cent[i]/PCB_DIV_MM for i in range(0,2)]))
print("Fids:", fids)
dest_folder = '/'.join(proj_file.split('/')[:-1])
dest_name = proj_file.split('/')[-1].removesuffix(".kicad_pro")
src_name = pcb_file.removesuffix(".kicad_pcb")
src_proj = src_name + ".kicad_pro"
try:
shutil.copy(src_name + ".kicad_dru", dest_folder + "/" + dest_name + ".kicad_dru")
except Exception:
pass
json_file = open(panel_file)
json_str = json_file.read()
panel_json = json.loads(json_str)
print(panel_json)
frame = Frame(panel_json["framing"]["type"], panel_json["framing"]["width"], panel_json["framing"]["space"])
board = Board(fids, panel_json["layout"].get("rotation", "0deg"), (sourceArea.GetWidth()/PCB_DIV_MM, sourceArea.GetHeight()/PCB_DIV_MM))
panel = Panel(panel_json["layout"]["space"], (int(panel_json["layout"]["rows"]), int(panel_json["layout"]["rows"])) ,frame, board)
for t in [panel.text, panel.text2, panel.text3, panel.text4]:
if t is not None:
panel_json.update(t)
# panel_json.update(panel.text3)
# json_file = open(src_proj)
# json_str = json_file.read()
# src = json.loads(json_str)
#
# json_file = open(proj_file)
# json_str = json_file.read()
# dest = json.loads(json_str)
#
json_file = open(panel_file, mode="w")
json.dump(panel_json, json_file, indent=4)
print("Finished pre_panel script")