diff --git a/.scripts/pre_panel.py b/.scripts/pre_panel.py index dbebfd6..7ee3f67 100644 --- a/.scripts/pre_panel.py +++ b/.scripts/pre_panel.py @@ -2,11 +2,17 @@ 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 num_to_mm(input: str) -> float: +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: @@ -14,42 +20,129 @@ def num_to_mm(input: str) -> float: 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: (float, float), rot: float, size: (float, float, float), just: (str, str)): + 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 = offset[0] - self.voff = offset[1] + self.hoff = float_to_str_mm(offset[0]) + self.voff = float_to_str_mm(offset[1]) self.rot = str(rot)+"deg" - self.width = size[0] - self.height = size[1] - self.thickness = size[2] + 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_json(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, + } + } class Frame: def __init__(self, ftype: str, width: str, spacing: str): self.ftype = ftype.lower() - self.width = num_to_mm(width) - self.spacing = num_to_mm(spacing) + 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, frame: Frame): - self.spacing = num_to_mm(spacing) + 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.text = "{boardTitle}-{boardRevision}" - if "frame" in self.frame.ftype or "tb" in self.frame.ftype: - if "frame" in self.frame.ftype: + 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: - self.text2 = None - self.text3 = None + 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 -print("Starting post_panel script") + 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") @@ -66,33 +159,29 @@ 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"]["spacing"]) -panel = Panel(panel_json["layout"]["space"], frame) +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) -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) +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) -# dest["board"]["design_settings"]["rule_severities"]["duplicate_footprints"] = "ignore" -# dest["board"]["design_settings"]["rule_severities"]["extra_footprint"] = "ignore" -# dest["board"]["design_settings"]["rule_severities"]["lib_footprint_issues"] = "ignore" -# dest["board"]["design_settings"]["rule_severities"]["lib_footprint_mismatch"] = "ignore" -# dest["board"]["design_settings"]["rule_severities"]["hole_near_hole"] = "ignore" -# dest["board"]["design_settings"]["rule_severities"]["silk_overlap"] = "ignore" -# dest["board"]["design_settings"]["rule_severities"]["silk_over_copper"] = "ignore" -# dest["board"]["design_settings"]["rule_severities"]["drill_out_of_range"] = "ignore" -# # # This one is just until kibot image is updated to 7.0.5 -# # dest["board"]["design_settings"]["rule_severities"]["copper_sliver"] = "ignore" -# dest["net_settings"]["classes"] = src["net_settings"]["classes"] -# dest["net_settings"]["netclass_patterns"] = src["net_settings"]["netclass_patterns"] +# 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) -with open(proj_file, mode="w") as json_file: - json.dump(dest, json_file, indent=2) - -print("Finished post_panel script") +print("Finished pre_panel script")