Files
2026-10-02 12:23:58 -04:00

102 lines
3.4 KiB
Python

"""Grid-export prototype STLs for chair_camera_pod.scad (0.4 mm pitch)."""
from pathlib import Path
import struct
import numpy as np
HERE = Path(__file__).resolve().parent
STEP = 0.4
def grid(lo, hi):
axes = [np.arange(a,b,STEP,dtype=np.float32)+STEP/2 for a,b in zip(lo,hi)]
return np.meshgrid(*axes,indexing="ij",sparse=True)
def box(X,Y,Z,x0,x1,y0,y1,z0,z1):
return ((X>=x0)&(X<x1)&(Y>=y0)&(Y<y1)&(Z>=z0)&(Z<z1))
def disk(X,Y,Z,x,y,r,z0,z1):
return ((X-x)**2+(Y-y)**2<=r*r)&(Z>=z0)&(Z<z1)
def xslot(X,Y,Z,a,b,y,r,z0,z1):
return (box(X,Y,Z,min(a,b),max(a,b),y-r,y+r,z0,z1)
|disk(X,Y,Z,a,y,r,z0,z1)|disk(X,Y,Z,b,y,r,z0,z1))
def yslot(X,Y,Z,x,a,b,r,z0,z1):
return (box(X,Y,Z,x-r,x+r,min(a,b),max(a,b),z0,z1)
|disk(X,Y,Z,x,a,r,z0,z1)|disk(X,Y,Z,x,b,r,z0,z1))
def tray():
lo,hi=(-39,-27,0),(39,27,14)
X,Y,Z=grid(lo,hi)
solid=box(X,Y,Z,-27,27,-27,27,0,3)
solid|=box(X,Y,Z,-27,-24,-27,27,3,13)
solid|=box(X,Y,Z,24,27,-27,27,3,13)
solid|=box(X,Y,Z,-27,27,24,27,3,13)
solid|=box(X,Y,Z,-39,-26,-18,18,0,4)
solid|=box(X,Y,Z,26,39,-18,18,0,4)
for x in (-17,17):
for y in (-17,17): solid|=disk(X,Y,Z,x,y,3.5,3,6)
for x in (-17,17):
for y in (-17,17): solid&=~xslot(X,Y,Z,x-2,x+2,y,1.5,-1,9)
for x in (-33,33): solid&=~yslot(X,Y,Z,x,-11,11,2.5,-1,6)
for x in (-25.5,25.5):
for y in (-23,23): solid&=~disk(X,Y,Z,x,y,0.8,5,14)
return solid,lo
def cover():
lo,hi=(-27,-27,0),(27,27,2.4)
X,Y,Z=grid(lo,hi)
solid=box(X,Y,Z,-27,27,-27,27,0,2.4)
solid&=~disk(X,Y,Z,0,6,9,-1,4)
for x in (-15.5,15.5):solid&=~yslot(X,Y,Z,x,0,11,3.5,-1,4)
for x in (-25.5,25.5):
for y in (-23,23):solid&=~disk(X,Y,Z,x,y,1.2,-1,4)
return solid,lo
def write_stl(path,solid,lo):
exposed=[]
for axis in range(3):
for sign in (-1,1):
neighbor=np.roll(solid,-sign,axis=axis)
face=solid&~neighbor
edge=[slice(None)]*3;edge[axis]=0 if sign==-1 else -1
face[tuple(edge)]=solid[tuple(edge)]
exposed.append((axis,sign,np.argwhere(face)))
facets=sum(2*len(v) for _,_,v in exposed)
with path.open("wb") as out:
out.write(b"Freddy concealed chair pod prototype".ljust(80,b"\0"))
out.write(struct.pack("<I",facets))
for axis,sign,points in exposed:
normal=[0.,0.,0.];normal[axis]=float(sign)
for i,j,k in points:
x0,y0,z0=(lo[0]+i*STEP,lo[1]+j*STEP,lo[2]+k*STEP)
x1,y1,z1=x0+STEP,y0+STEP,z0+STEP
if axis==0:
x=x1 if sign==1 else x0
quad=[(x,y0,z0),(x,y1,z0),(x,y1,z1),(x,y0,z1)]
elif axis==1:
y=y1 if sign==1 else y0
quad=[(x0,y,z0),(x0,y,z1),(x1,y,z1),(x1,y,z0)]
else:
z=z1 if sign==1 else z0
quad=[(x0,y0,z),(x1,y0,z),(x1,y1,z),(x0,y1,z)]
if sign==-1:quad.reverse()
for a,b,c in ((0,1,2),(0,2,3)):
out.write(struct.pack("<12fH",*normal,*quad[a],*quad[b],*quad[c],0))
print(path.name,facets,"facets",round(path.stat().st_size/1e6,1),"MB")
if __name__=="__main__":
for name,build in (("chair_camera_tray_draft.stl",tray),
("chair_camera_cover_draft.stl",cover)):
solid,lo=build();write_stl(HERE/name,solid,lo)