Files
kicad2panel/cleanup.py
2026-06-11 18:31:24 +02:00

96 lines
3.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import pcbnew
from shapely.geometry import MultiPolygon, Polygon
# ---------------------------------------------------------------------------
# KiKit postprocess hook cleanup.py
#
# 1. Copy all Edge.Cuts content (substrate rings) to Eco1_User as segments,
# EXCEPT the outermost panel rectangle.
# ---------------------------------------------------------------------------
TOLERANCE_NM = 1_000 # 1 µm
def _mm(nm_val):
return f"{pcbnew.ToMM(int(nm_val)):.4f} mm"
def _collect_rings(geom):
"""Return all rings as list of (shapely_ring, coord_list)."""
rings = []
if isinstance(geom, Polygon):
rings.append((geom.exterior, list(geom.exterior.coords)))
for interior in geom.interiors:
rings.append((interior, list(interior.coords)))
elif isinstance(geom, MultiPolygon):
for poly in geom.geoms:
rings.extend(_collect_rings(poly))
return rings
def _is_outer_frame(ring_geom, x0, y0, x1, y1, tol=TOLERANCE_NM):
"""True if the ring's bounding box equals the panel bounding box."""
b = ring_geom.bounds
return (abs(b[0] - x0) <= tol and abs(b[1] - y0) <= tol and
abs(b[2] - x1) <= tol and abs(b[3] - y1) <= tol)
def _shapely_to_segments(board, coords, layer, width_mm=0.05):
pts = list(coords)
if not pts:
return 0
if pts[0] != pts[-1]:
pts.append(pts[0])
count = 0
for i in range(len(pts) - 1):
seg = pcbnew.PCB_SHAPE(board)
seg.SetShape(pcbnew.SHAPE_T_SEGMENT)
seg.SetLayer(layer)
seg.SetWidth(pcbnew.FromMM(width_mm))
seg.SetStart(pcbnew.VECTOR2I(int(pts[i][0]), int(pts[i][1])))
seg.SetEnd (pcbnew.VECTOR2I(int(pts[i+1][0]), int(pts[i+1][1])))
board.Add(seg)
count += 1
return count
def kikitPostprocess(panel, arg):
print("=" * 60)
print("[cleanup] START")
board = panel.board
substrate = panel.boardSubstrate
# outer panel bbox
b = substrate.bounds()
x0, y0, x1, y1 = int(b[0]), int(b[1]), int(b[2]), int(b[3])
print(f"[cleanup] Panel bbox: ({_mm(x0)},{_mm(y0)})({_mm(x1)},{_mm(y1)})")
# get substrate geometry
geom = None
for attr in ("substrates", "substrate", "_substrate", "geometry"):
if hasattr(substrate, attr):
geom = getattr(substrate, attr)
break
if geom is None:
print("[cleanup] ERROR: cannot access substrate geometry")
return
rings = _collect_rings(geom)
print(f"[cleanup] Total rings in substrate: {len(rings)}")
total = 0
for i, (ring_geom, coords) in enumerate(rings):
rb = ring_geom.bounds
if _is_outer_frame(ring_geom, x0, y0, x1, y1):
print(f"[cleanup] ring[{i}] pts={len(coords)-1} → OUTER FRAME, skipped")
continue
n = _shapely_to_segments(board, coords, pcbnew.Eco1_User)
total += n
print(f"[cleanup] ring[{i}] pts={len(coords)-1}"
f" bbox=({_mm(rb[0])},{_mm(rb[1])})({_mm(rb[2])},{_mm(rb[3])})"
f"{n} segments on Eco1_User")
print(f"[cleanup] Total Eco1_User segments added: {total}")
print("[cleanup] END")
print("=" * 60)