建立方向盘项目初始版本

This commit is contained in:
2026-10-29 22:04:55 +08:00
commit 9962cbfbce
834 changed files with 1519203 additions and 0 deletions

View File

@@ -0,0 +1,53 @@
"""Render a 2D overview of the generated STL plate using Pillow.
The preview is only a placement guide; the STL is the printing artifact.
"""
from pathlib import Path
import json, struct
from PIL import Image, ImageDraw, ImageFont, ImageChops, ImageFilter
root=Path(__file__).resolve().parent.parent
out=root/'models'/'pcd50_print_plate'
source=root/'models'/'pcd50_open_pillar_v1'
info=json.loads((out/'布局检查.json').read_text(encoding='utf-8'))
canvas=Image.new('RGB',(1220,1060),'#f7f9fc')
d=ImageDraw.Draw(canvas)
font_path='C:/Windows/Fonts/msyh.ttc'
title=ImageFont.truetype(font_path,42)
font=ImageFont.truetype(font_path,25)
small=ImageFont.truetype(font_path,21)
d.text((70,38),'一盘打印:支架 + 4 个 0.5 mm 垫片',font=title,fill='#1a2942')
d.text((70,104),'俯视排版 · 模型保持原尺寸 · 单位:mm',font=font,fill='#52627b')
scale=10.0; ox=250; oy=900
def xy(x,y): return (round(ox+x*scale),round(oy-y*scale))
def triangle_vertices(path):
data=path.read_bytes()
count=struct.unpack_from('<I',data,80)[0]
if len(data)!=84+50*count:raise ValueError('Invalid binary STL')
return [((t[3],t[4],t[5]),(t[6],t[7],t[8]),(t[9],t[10],t[11]))
for t in struct.iter_unpack('<12fH',data[84:])]
def show_part(path, target_bounds, fill):
tris=triangle_vertices(path)
source_x=min(v[0] for tri in tris for v in tri)
source_y=min(v[1] for tri in tris for v in tri)
dx,dy=target_bounds[0]-source_x,target_bounds[2]-source_y
mask=Image.new('L',canvas.size,0);md=ImageDraw.Draw(mask)
for tri in tris:
md.polygon([xy(v[0]+dx,v[1]+dy) for v in tri],fill=255)
ink=Image.new('RGB',canvas.size,fill);canvas.paste(ink,(0,0),mask)
edge=ImageChops.subtract(mask,mask.filter(ImageFilter.MinFilter(5)))
canvas.paste(Image.new('RGB',canvas.size,'#20314b'),(0,0),edge)
# Plate bounds reflect model footprint, not an assumed printer bed.
d.rounded_rectangle([215,oy-725,ox+755,oy+35],radius=12,fill='#ffffff',outline='#c3cfdf',width=3)
for ob in info['main']['objects']:
part='EncoderBracket.stl' if ob['name']=='Bracket' else 'Shim05.stl'
show_part(source/part,ob['bounds_mm'],'#3c6fba' if ob['name']=='Bracket' else '#e3a53e')
d=ImageDraw.Draw(canvas)
d.text((270,185),'支架 × 1',font=font,fill='#214b87')
d.text((270,922),'0.5 mm 垫片 × 4',font=font,fill='#8a5600')
d.text((70,1000),'模型约 71.6 × 69.0 mm,件间净距至少 8.0 mm',font=small,fill='#52627b')
canvas.save(out/'打印排版预览.png')