# -*- coding: utf-8 -*- u"""由 make_v8.py 文本派生 make_v9.py(槽宽 6 / 竖筋 2.0 / 横筋 2.0 中心距 12 / 最长槽段 10)。""" import io import sys sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', write_through=True) T = u'C:\\Users\\35138\\.claude\\jobs\\11836093\\tmp\\' s = open(T + 'make_v8.py', encoding='utf-8').read() def rep(old, new, n=1): global s c = s.count(old) if c != n: raise SystemExit(u'锚点 %r 出现 %d 次(期望 %d)' % (old[:60], c, n)) s = s.replace(old, new) rep(u'u"TopShell_v8.SLDPRT\'"', u'u"TopShell_v9.SLDPRT\'"') rep(u'u"\'TOPSHELL_V8\'"', u'u"\'TOPSHELL_V9\'"') rep(u"GR_R, GR_W, GR_RIB = 32.0, 4.5, 1.2\nXB_Z, XB_W = (-16.0, 0.0, 16.0), 1.2 # 横撑中心(相对风扇中心 z)与宽度", u"GR_R, GR_W, GR_RIB = 32.0, 6.0, 2.0 # v9:槽宽 6、竖筋 2.0(用户选 ③)\n" u"XB_W, XB_SEG = 2.0, 10.0 # 横筋宽 2.0,最长槽段 10 ⇒ 横筋中心距 12\n" u"XB_P = XB_SEG + XB_W\n" u"XB_Z = tuple(k * XB_P for k in range(-int(GR_R // XB_P) - 1, int(GR_R // XB_P) + 2))") a = s.index(u"def slot_segments(L_):") b = s.index(u"def seg_area(z0, z1, r0, r1):") NEWSEG = u'''def slot_segments(L_): u"""一条槽被横筋切成的段:[(z0, z1, round0, round1)],z 相对风扇中心;round = 该端是真正的槽头(半圆)。 v9 通用规则:横筋可以切到槽头附近;短到放不下「端头 + 0.8 直边」的碎段做成实心(不画)。""" r = GR_W / 2 h = L_ / 2 cuts = sorted((c - XB_W / 2, c + XB_W / 2) for c in XB_Z if c + XB_W / 2 > -h and c - XB_W / 2 < h) ivs, z = [], -h for lo, hi in cuts: ivs.append((z, lo)) z = hi ivs.append((z, h)) segs = [] for z0, z1 in ivs: r0, r1 = abs(z0 + h) < 1e-9, abs(z1 - h) < 1e-9 need = (r if r0 else 0.0) + (r if r1 else 0.0) + 0.8 if z1 - z0 < need: continue segs.append((z0, z1, r0, r1)) return segs, 0 ''' s = s[:a] + NEWSEG + s[b:] rep(u"""for _ys, _L in GRS: _segs, _nc = slot_segments(_L) A_SLOTS += sum(seg_area(*sg) for sg in _segs) N_FLAT += 2 * _nc LONGEST = max([LONGEST] + [sg[1] - sg[0] for sg in _segs])""", u"""N_ROUND = 0 N_SEG = 0 for _ys, _L in GRS: _segs, _ = slot_segments(_L) A_SLOTS += sum(seg_area(*sg) for sg in _segs) N_FLAT += sum(int(not sg[2]) + int(not sg[3]) for sg in _segs) N_ROUND += sum(int(sg[2]) + int(sg[3]) for sg in _segs) N_SEG += len(_segs) LONGEST = max([LONGEST] + [sg[1] - sg[0] for sg in _segs])""") rep(u"""P(u' 格栅:%d 条竖槽(宽 %.1f 筋 %.1f 外包 R%.0f)+ 3 条横撑 %.1f,开孔 %.1f mm²(原 Ø60 的 %.1f%%),最长槽段 %.1f' % (len(GRS), GR_W, GR_RIB, GR_R, XB_W, A_SLOTS, A_SLOTS / (math.pi * 900) * 100, LONGEST))""", u"""P(u' 格栅:%d 条竖槽(宽 %.1f 竖筋 %.1f 外包 R%.0f)+ 横筋 %.1f(中心距 %.0f),共 %d 段;开孔 %.1f mm²(原 Ø60 的 %.1f%%),最长槽段 %.1f;半圆端 %d、平端 %d' % (len(GRS), GR_W, GR_RIB, GR_R, XB_W, XB_P, N_SEG, A_SLOTS, A_SLOTS / (math.pi * 900) * 100, LONGEST, N_ROUND, N_FLAT))""") rep(u""" P(u' 槽头半圆柱 +%d(期望 %d)%s;横撑平端面 +%d(期望 %d)%s;风扇孔在位 %s' % (caps, 2 * len(GRS), u'✅' if caps == 2 * len(GRS) else u'⛔', flats, N_FLAT, u'✅' if flats == N_FLAT else u'⛔', u'✅' if fan_ok else u'⛔')) if not (ok_area and caps == 2 * len(GRS) and flats == N_FLAT and fan_ok):""", u""" P(u' 槽头半圆柱 +%d(期望 %d)%s;横筋平端面 +%d(期望 %d)%s;风扇孔在位 %s' % (caps, N_ROUND, u'✅' if caps == N_ROUND else u'⛔', flats, N_FLAT, u'✅' if flats == N_FLAT else u'⛔', u'✅' if fan_ok else u'⛔')) if not (ok_area and caps == N_ROUND and flats == N_FLAT and fan_ok):""") # 顶盖直方图里 R2.25 的期望(v7 的 4×len(GRS))要换成 N_ROUND×2(两面墙)与新半径 rep(u"'# -*- coding: utf-8 -*-\\n# v8:格栅竖槽加 3 条横撑(最长悬空筋 64 → 16),其余同 v7\\n'", u"'# -*- coding: utf-8 -*-\\n# v9:格栅 槽宽 6 / 竖筋 2.0 / 横筋 2.0 中心距 12(最长槽段 10),其余同 v7\\n'") rep(u"s = s[:a] + NEW + s[b:]\n", u"s = s[:a] + NEW + s[b:]\n" u"_old_h = u\"WANT_H = {0.7: 8, 0.75: 2 * SLOT_N, 0.8: 1, 1.5: 4, 2.1: 4, round(GR_W / 2, 2): 4 * len(GRS), 2.6: 8, 3.0: 4, 30.0: 0}\"\n" u"if s.count(_old_h) != 1:\n" u" raise SystemExit(u'直方图锚点')\n" u"# ⚠ 槽宽 6 ⇒ 槽头半径 3.0,与顶盖竖边圆角 R3 同半径:必须累加,不能在字典字面量里重复键(后者会覆盖前者)\n" u"s = s.replace(_old_h, u\"WANT_H = {0.7: 8, 0.75: 2 * SLOT_N, 0.8: 1, 1.5: 4, 2.1: 4, 2.6: 8, 3.0: 4, 30.0: 0}\\n\"\n" u" u\"WANT_H[round(GR_W / 2, 2)] = WANT_H.get(round(GR_W / 2, 2), 0) + 2 * N_ROUND\")\n") rep(u"open(T + 'topshell_v8.py', 'w', encoding='utf-8').write(s)\nprint(u'写出 topshell_v8.py')", u"open(T + 'topshell_v9.py', 'w', encoding='utf-8').write(s)\nprint(u'写出 topshell_v9.py')") rep(u"""(u"(u'TopShell_v7.SLDPRT',", u"(u'TopShell_v8.SLDPRT',"), (u"((u'v7_iso', 7),)", u"((u'v8_iso', 7),)")""", u"""(u"(u'TopShell_v7.SLDPRT',", u"(u'TopShell_v9.SLDPRT',"), (u"((u'v7_iso', 7),)", u"((u'v9_iso', 7),)")""") rep(u"open(T + 'place_v8.py', 'w', encoding='utf-8').write(p)\nprint(u'写出 place_v8.py')", u"open(T + 'place_v9.py', 'w', encoding='utf-8').write(p)\nprint(u'写出 place_v9.py')") rep(u'rsrc = rsrc.replace(u"v7_", u"v8_")', u'rsrc = rsrc.replace(u"v7_", u"v9_")') rep(u"v8_west_zoom", u"v9_west_zoom", 2) rep(u"open(T + 'render_v8.py', 'w', encoding='utf-8').write(rsrc)\nprint(u'写出 render_v8.py')", u"open(T + 'render_v9.py', 'w', encoding='utf-8').write(rsrc)\nprint(u'写出 render_v9.py')") open(T + 'make_v9.py', 'w', encoding='utf-8').write(s) print(u'写出 make_v9.py')