Skip to content

Commit

Permalink
Simplify layout templates footprint position handling
Browse files Browse the repository at this point in the history
  • Loading branch information
adamws committed Jun 15, 2024
1 parent a35d4a8 commit 4724d1a
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 68 deletions.
42 changes: 21 additions & 21 deletions src/kle2netlist/circuits/atmega32u4.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,25 +47,25 @@
FOOTPRINTS = {"v1": V1_FOOTPRINTS, "v2": V2_FOOTPRINTS}

# fmt: off
V1_POSITIONS = {
"C1": { "x": 34.01, "y": 1.69, "rot": 45.0, "side": "Back" },
"C2": { "x": 33.65, "y": -2.78, "rot": -45.0, "side": "Back" },
"C3": { "x": 11.58, "y": 4.24, "rot": 180.0, "side": "Back" },
"C4": { "x": 21.29, "y": -8.15, "rot": 180.0, "side": "Back" },
"C5": { "x": 24.2, "y": 9.37, "rot": -90.0, "side": "Back" },
"C6": { "x": 11.58, "y": -3.7, "rot": 180.0, "side": "Back" },
"C7": { "x": 16.97, "y": -8.15, "rot": 180.0, "side": "Back" },
"C8": { "x": 21.29, "y": -9.74, "rot": 180.0, "side": "Back" },
"J1": { "x": 18.75, "y": -27.275, "rot": 0.0, "side": "Back" },
"R1": { "x": 17.85, "y": -12.28 , "rot": 90.0, "side": "Back" },
"R2": { "x": 19.55, "y": -12.27, "rot": 90.0, "side": "Back" },
"R3": { "x": 16.96, "y": 9.37, "rot": -90.0, "side": "Back" },
"R4": { "x": 32.01, "y": -5.39, "rot": -135.0, "side": "Back" },
"RST": { "x": 41.75, "y": -6.0, "rot": 90.0, "side": "Back" },
"U1": { "x": 20.98, "y": 0.25, "rot": -90.0, "side": "Back" },
"U2": { "x": 18.7, "y": -18.375, "rot": 0.0, "side": "Back" },
"Y1": { "x": 31.6, "y": -0.68, "rot": 135.0, "side": "Back" }
}
V1_POSITIONS = [
{ "ref": "C1", "x": 34.01, "y": 1.69, "rotation": 45.0, "side": "Back" },
{ "ref": "C2", "x": 33.65, "y": -2.78, "rotation": -45.0, "side": "Back" },
{ "ref": "C3", "x": 11.58, "y": 4.24, "rotation": 180.0, "side": "Back" },
{ "ref": "C4", "x": 21.29, "y": -8.15, "rotation": 180.0, "side": "Back" },
{ "ref": "C5", "x": 24.2, "y": 9.37, "rotation": -90.0, "side": "Back" },
{ "ref": "C6", "x": 11.58, "y": -3.7, "rotation": 180.0, "side": "Back" },
{ "ref": "C7", "x": 16.97, "y": -8.15, "rotation": 180.0, "side": "Back" },
{ "ref": "C8", "x": 21.29, "y": -9.74, "rotation": 180.0, "side": "Back" },
{ "ref": "J1", "x": 18.75, "y": -27.275, "rotation": 0.0, "side": "Back" },
{ "ref": "R1", "x": 17.85, "y": -12.28 , "rotation": 90.0, "side": "Back" },
{ "ref": "R2", "x": 19.55, "y": -12.27, "rotation": 90.0, "side": "Back" },
{ "ref": "R3", "x": 16.96, "y": 9.37, "rotation": -90.0, "side": "Back" },
{ "ref": "R4", "x": 32.01, "y": -5.39, "rotation": -135.0, "side": "Back" },
{ "ref": "RST", "x": 41.75, "y": -6.0, "rotation": 90.0, "side": "Back" },
{ "ref": "U1", "x": 20.98, "y": 0.25, "rotation": -90.0, "side": "Back" },
{ "ref": "U2", "x": 18.7, "y": -18.375, "rotation": 0.0, "side": "Back" },
{ "ref": "Y1", "x": 31.6, "y": -0.68, "rotation": 135.0, "side": "Back" }
]
# fmt: on

POSITIONS = {"v1": V1_POSITIONS, "v2": None}
Expand Down Expand Up @@ -209,7 +209,7 @@ def atmega32u4_au_v2(rows, columns):
if __name__ == "__main__":
import pcbnew

from kle2netlist.pcb import set_positions
from kle2netlist.pcb import Footprint, set_positions
from kle2netlist.skidl import set_skidl_search_path

set_skidl_search_path()
Expand All @@ -223,5 +223,5 @@ def atmega32u4_au_v2(rows, columns):
circuit.generate_pcb(file_=board_path, fp_libs=libraries)

board = pcbnew.LoadBoard(board_path)
set_positions(board, POSITIONS["v1"])
set_positions(board, [Footprint.fromdict(d) for d in POSITIONS["v1"]])
pcbnew.SaveBoard(board_path, board)
81 changes: 34 additions & 47 deletions src/kle2netlist/pcb.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from __future__ import annotations

import json
from typing import Dict, Union
from dataclasses import asdict, dataclass
from pprint import pprint
from typing import List, Type

import pcbnew
from kbplacer.board_modifier import (
Expand All @@ -11,68 +13,53 @@
set_rotation,
set_side,
)
from kbplacer.element_position import ElementPosition, Side
from kbplacer.element_position import Side


class PositionEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, ElementPosition):
return {"x": obj.x, "y": obj.y, "rot": obj.orientation, "side": obj.side}
return super().default(obj)
@dataclass
class Footprint:
ref: str
x: float
y: float
rotation: float
side: Side

@classmethod
def fromdict(cls: Type[Footprint], data: dict) -> Footprint:
return cls(**data)

class PositionDecoder(json.JSONDecoder):
def __init__(self):
json.JSONDecoder.__init__(self, object_hook=PositionDecoder.from_dict)

@staticmethod
def from_dict(d):
if set(d.keys()) == set(["x", "y", "rot", "side"]):
return PositionDecoder.element_position_from_dict(d)
return d

@staticmethod
def element_position_from_dict(d) -> ElementPosition:
return ElementPosition(
d["x"],
d["y"],
d["rot"],
Side.get(d["side"]),
)


def get_positions(board: pcbnew.BOARD) -> Dict[str, ElementPosition]:
positions = {}
def get_positions(board: pcbnew.BOARD) -> List[Footprint]:
positions = []
for fp in board.GetFootprints():
reference = fp.GetReference()
position = ElementPosition(
position = Footprint(
ref=fp.GetReference(),
x=pcbnew.ToMM(fp.GetX()),
y=pcbnew.ToMM(fp.GetY()),
orientation=get_orientation(fp),
rotation=get_orientation(fp),
side=get_side(fp),
)
positions[reference] = position
positions.append(position)

return dict(sorted(positions.items()))
return sorted(positions, key=lambda x: x.ref)


def set_positions(
board: pcbnew.BOARD, positions: Union[Dict[str, ElementPosition], Dict[str, Dict]]
) -> None:
for ref, position in positions.items():
fp = board.FindFootprintByReference(ref)
if not isinstance(position, ElementPosition):
position = PositionDecoder.element_position_from_dict(position)
set_side(fp, position.side)
set_rotation(fp, position.orientation)
set_position(fp, pcbnew.wxPointMM(position.x, position.y))
def set_positions(board: pcbnew.BOARD, footprints: List[Footprint]) -> None:
for f in footprints:
fp = board.FindFootprintByReference(f.ref)
set_side(fp, f.side)
set_rotation(fp, f.rotation)
set_position(fp, pcbnew.wxPointMM(f.x, f.y))


if __name__ == "__main__":
pcb_file = "./kicad-templates/atmega32u4-au-v1/atmega32u4-au-v1.kicad_pcb"
board = pcbnew.LoadBoard(pcb_file)
positions = get_positions(board)
json_encoded = json.dumps(positions, indent=4, cls=PositionEncoder)
print(json_encoded)
json_decoded = json.loads(json_encoded, cls=PositionDecoder)
set_positions(board, json_decoded)
json_encoded = json.dumps(positions, default=lambda x: asdict(x))

json_decoded = json.loads(json_encoded)
pprint(json_decoded)

positions = [Footprint.fromdict(d) for d in json_decoded]
set_positions(board, positions)

0 comments on commit 4724d1a

Please sign in to comment.