diff --git a/.scripts/post_panel.py b/.scripts/post_panel.py index 812700d..ae457c5 100644 --- a/.scripts/post_panel.py +++ b/.scripts/post_panel.py @@ -33,8 +33,8 @@ 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" +# # 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"] diff --git a/.scripts/pre_panel.py b/.scripts/pre_panel.py new file mode 100644 index 0000000..d761e18 --- /dev/null +++ b/.scripts/pre_panel.py @@ -0,0 +1,184 @@ +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),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.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"]["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) + + 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") diff --git a/kibot-ci.yml b/kibot-ci.yml index 9ab0517..727e218 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -111,6 +111,7 @@ image: PCB=$(find $d/*.kicad_pcb) mkdir -p panels/$NAME echo "panelising" + python3 .gitlab/.scripts/pre_panel.py $PCB $JSON kikit panelize -p $JSON $PCB panels/$NAME/$NAME.kicad_pcb cp .gitlab/micromelon_default/micromelon_default.kicad_sch panels/$NAME/$NAME.kicad_sch cp $d/fp-lib-table panels/$NAME/