import json import sys from kikit.common import findBoardBoundingBox from kikit.panelize_ui_impl import buildText from kikit.panelize_ui_sections import ppText from kikit.defs import * from pcbnewTransition.pcbnew import LoadBoard PCB_DIV_MM = 1000000 pcb_file = sys.argv[1] panel_file = sys.argv[2] 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.layer=Layer.F_SilkS 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 flip(self): self.layer=Layer.B_SilkS rot = float(self.rot.replace("deg", "")) rot += 180.0 self.rot = str(rot)+"deg" return self 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, "layer": int(self.layer), } } 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: tuple[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 = {} self.dims = [self.gaps[i]*self.spacing + self.grid[i]*board.dims[i] + frame.extra_d[i] for i in range(0,2)] self.spacing = [self.spacing + board.dims[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'), ('left', 'center')) txt_rot = 90 self.text.update(Text("{boardTitle}-{boardRevision}", txt_loc[0], txt_off[0], txt_rot, just=txt_just[0]).to_dict(len(self.text))) spacer = " " txt =\ "PNL (x,y): (" + float_to_str_mm(self.dims[0],4) + ", " + float_to_str_mm(self.dims[1],4) + ")\n" +\ "SPA (x,y): (" + float_to_str_mm(self.spacing[0],2) + ", " + float_to_str_mm(self.spacing[1],2) +")\n" +\ "BRD (x,y): (" + float_to_str_mm(board.dims[0],4) + ", " + float_to_str_mm(board.dims[1],4) + "), " +\ "FIDS (x,y) : " + board.fids self.text.update(Text(txt, txt_loc[1], txt_off[1], txt_rot, just=txt_just[1]).to_dict(1)) if "frame" in self.frame.ftype: txt_orig = [ Text("ORIGX ->", "bl", (arrow_off[0], -arrow_off[1]), 90, just=("right", "center")), Text("ORIGY ->", "bl", (arrow_off[1], -arrow_off[0]), 0, just=("right", "center")) ] for txt in txt_orig: self.text.update(txt.to_dict(len(self.text))) self.text.update(txt.flip().to_dict(len(self.text))) def kikitPostprocess(panel, arg): print("arg:", arg) text_dict = eval(arg) for t in text_dict.values(): ppText(t) print(t["thickness"]) t["plugin"] = None buildText(t,panel) # panel.addText(t.text, position=, orientation=t.rot, # width=t.width, height=t.height, thickness=t.thickness, # hJustify=t.hjustify, # vJustify=t.vjustify, # layer=t.layer): print("Finished post panel script") if __name__ == '__main__': print("Starting pre_panel script") board = LoadBoard(pcb_file) sourceArea = findBoardBoundingBox(board) 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)])) json_file = open(panel_file) json_str = json_file.read() panel_json = json.loads(json_str) frame = Frame(panel_json["framing"]["type"], panel_json["framing"]["width"], panel_json["framing"]["slotwidth"]) board = Board(fids, panel_json["layout"].get("rotation", "0deg"), (sourceArea.GetWidth()/PCB_DIV_MM, sourceArea.GetHeight()/PCB_DIV_MM)) panel = Panel(panel_json["layout"]["hspace"], (int(panel_json["layout"]["rows"]), int(panel_json["layout"]["cols"])), frame, board) import pathlib panel_json["post"]["script"] = str(pathlib.Path(__file__).resolve()) panel_json["post"]["scriptarg"] = str(panel.text) json_file = open(panel_file, mode="w") json.dump(panel_json, json_file, indent=4) print("Finished pre_panel script")