建立方向盘项目初始版本
This commit is contained in:
53
scripts/render_pcd50_print_plate_preview.py
Normal file
53
scripts/render_pcd50_print_plate_preview.py
Normal 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')
|
||||
Reference in New Issue
Block a user