sync: HP_BOWEI 2026-10-15
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
"""根图(第 1 页):左栏层次页符号 + 右侧内嵌 drawio 框图 PNG。
|
||||
|
||||
跨页连接一律用全局标签,层次页不需要 sheet pin。子页的 sheet_uuid 由 uid("sh", 文件名)
|
||||
推出,与 page.Page 的约定一致,所以根图和子图可以各自单独重生成。
|
||||
|
||||
from schgen.root import write_root
|
||||
write_root(prj, [("02_Power.kicad_sch", "02 电源"), ...], png=r"...\\diagram.png",
|
||||
title="MyBoard", note="一段说明文字")
|
||||
|
||||
插图:KiCad 对没有 pHYs 的 PNG 按 300DPI 解释,scale=1 时宽 = 像素/300*25.4mm(G-0022),
|
||||
据此反算 scale;(image (at 中心)) 给的是中心不是左上角;base64 每行 76 字符。
|
||||
"""
|
||||
import base64
|
||||
import io
|
||||
import os
|
||||
import struct
|
||||
|
||||
from .kicad_lib import uid, esc
|
||||
from .layout import PAPER
|
||||
|
||||
KICAD_BITMAP_DPI = 300.0
|
||||
|
||||
|
||||
def image_block(png, x0, y0, max_w, max_h, key="img"):
|
||||
raw = io.open(png, "rb").read()
|
||||
px, py = struct.unpack(">II", raw[16:24])
|
||||
nat_w, nat_h = px / KICAD_BITMAP_DPI * 25.4, py / KICAD_BITMAP_DPI * 25.4
|
||||
scale = min(max_w / nat_w, max_h / nat_h)
|
||||
w, h = nat_w * scale, nat_h * scale
|
||||
cx, cy = x0 + w / 2.0, y0 + h / 2.0
|
||||
b64 = base64.b64encode(raw).decode("ascii")
|
||||
body = "\n\t\t\t".join('"%s"' % b64[i:i + 76] for i in range(0, len(b64), 76))
|
||||
blk = ('\t(image\n\t\t(at %.3f %.3f)\n\t\t(scale %.6f)\n\t\t(uuid "%s")\n'
|
||||
'\t\t(data %s\n\t\t)\n\t)' % (cx, cy, scale, uid("root", key, os.path.basename(png)), body)) # 只用文件名:工程搬目录后重生成结果不变
|
||||
return blk, (x0, y0, w, h)
|
||||
|
||||
|
||||
def write_root(prj, sheets, png=None, title=None, note="", paper="A2",
|
||||
col_w=110.0, sheet_h=18.0, gap=10.0, img_note=None):
|
||||
"""sheets: [(文件名, 显示名), ...],按顺序排在左栏(页码 2、3…)。"""
|
||||
PW, PH = PAPER[paper]
|
||||
title = title or prj.name
|
||||
root_u = uid("root", prj.name)
|
||||
out = ['(kicad_sch (version 20231120) (generator "kicad_flow_schgen") (generator_version "8.0")',
|
||||
' (uuid "%s")' % root_u,
|
||||
' (paper "%s")' % paper,
|
||||
' (title_block (title "%s") (rev "%s") (company "%s"))'
|
||||
% (esc(title), prj.rev, esc(prj.company)),
|
||||
' (lib_symbols)']
|
||||
x = 26.0
|
||||
y = 24.0
|
||||
if note:
|
||||
out.append(' (text "%s" (at %.1f %.1f 0) (effects (font (size 1.8 1.8)) (justify left top))'
|
||||
' (uuid "%s"))' % (esc(note), x, y, uid("root", "note")))
|
||||
y += 6.0 + 2.6 * (note.count("\n") + 1)
|
||||
for i, (fn, name) in enumerate(sheets):
|
||||
sy = y + 6.0 + i * (sheet_h + gap)
|
||||
out.append(
|
||||
' (sheet (at %.1f %.1f) (size %.1f %.1f) (fields_autoplaced yes)\n'
|
||||
' (stroke (width 0.1524) (type solid)) (fill (color 0 0 0 0.0))\n'
|
||||
' (uuid "%s")\n'
|
||||
' (property "Sheetname" "%s" (at %.1f %.2f 0)\n'
|
||||
' (effects (font (size 1.8 1.8)) (justify left bottom)))\n'
|
||||
' (property "Sheetfile" "%s" (at %.1f %.2f 0)\n'
|
||||
' (effects (font (size 1.4 1.4)) (justify left top)))\n'
|
||||
' (instances (project "%s" (path "/%s" (page "%d"))))\n'
|
||||
' )' % (x, sy, col_w, sheet_h, uid("sh", fn), esc(name), x, sy - 1.0,
|
||||
fn, x, sy + sheet_h + 1.0, prj.name, root_u, i + 2))
|
||||
info = None
|
||||
if png:
|
||||
ix0 = x + col_w + 14.0
|
||||
iy0 = 24.0
|
||||
blk, info = image_block(png, ix0, iy0, PW - 14.0 - ix0, PH - 40.0 - iy0 - 8.0)
|
||||
out.append(blk)
|
||||
if img_note:
|
||||
out.append(' (text "%s" (at %.1f %.1f 0) (effects (font (size 1.6 1.6)) (justify left top))'
|
||||
' (uuid "%s"))' % (esc(img_note), ix0, iy0 + info[3] + 3.0,
|
||||
uid("root", "imgnote")))
|
||||
out.append(' (sheet_instances (path "/" (page "1")))')
|
||||
out.append(')')
|
||||
p = os.path.join(prj.out_dir, prj.name + ".kicad_sch")
|
||||
io.open(p, "w", encoding="utf-8").write("\n".join(out) + "\n")
|
||||
print("根图 %s (%.0f KB)%s" % (p, os.path.getsize(p) / 1024.0,
|
||||
" 框图 %.0fx%.0f mm" % (info[2], info[3]) if info else ""))
|
||||
return p
|
||||
|
||||
|
||||
def write_project(prj):
|
||||
"""最小 .kicad_pro(没有它 KiCad 打不开工程);已存在就不动。"""
|
||||
p = os.path.join(prj.out_dir, prj.name + ".kicad_pro")
|
||||
if not os.path.exists(p):
|
||||
io.open(p, "w", encoding="utf-8").write(
|
||||
'{\n "meta": {"filename": "%s.kicad_pro", "version": 1},\n'
|
||||
' "schematic": {"legacy_lib_dir": "", "legacy_lib_list": []},\n'
|
||||
' "sheets": [],\n "boards": [],\n "libraries": {"pinned_footprint_libs": [],'
|
||||
' "pinned_symbol_libs": []}\n}\n' % prj.name)
|
||||
return p
|
||||
|
||||
|
||||
def write_lib_tables(prj, sym_libs=(), fp_libs=()):
|
||||
"""工程级 sym-lib-table / fp-lib-table,用 ${KIPRJMOD} 相对路径。
|
||||
改完必须**整个退出 KiCad 再重启**才生效(G-0020)。"""
|
||||
def table(kind, libs):
|
||||
rows = ['(%s_lib_table' % kind, ' (version 7)']
|
||||
for name, rel in libs:
|
||||
# 绝对路径原样写;ipots 工程里 ${KIPRJMOD} 版 fp-lib-table 曾没被认到(多半是没重启)
|
||||
uri = rel if os.path.isabs(rel) else "${KIPRJMOD}/" + rel
|
||||
rows.append(' (lib (name "%s") (type "KiCad") (uri "%s") (options "")'
|
||||
' (descr ""))' % (name, uri.replace("\\", "/")))
|
||||
rows.append(')')
|
||||
return "\n".join(rows) + "\n"
|
||||
if sym_libs:
|
||||
io.open(os.path.join(prj.out_dir, "sym-lib-table"), "w", encoding="utf-8").write(
|
||||
table("sym", sym_libs))
|
||||
if fp_libs:
|
||||
io.open(os.path.join(prj.out_dir, "fp-lib-table"), "w", encoding="utf-8").write(
|
||||
table("fp", fp_libs))
|
||||
Reference in New Issue
Block a user