Files
wheel/scripts/render_pcd50_print_plate_preview.py

54 lines
2.4 KiB
Python
Raw Permalink 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.
"""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')