Below you can find my python code to make a vase for 3D-printing. The vase looks nice on my screen so the vertices and the faces seem to be perfect. However, when sending the .stl file produced to a 3D-printer the vase comes out as a filled solid - no room for water and flowers! I have tried to slice the vase the the program "Cura". It seems that the slices are full disks, not rings as intended, at some values of z but far from all. I don't expect anybody to read the full program (I'm a very poor programmer) but my hope is that someone can give a hint as to how I can improve the writing of the .stl file.
Poul Riis #!/usr/bin/env python #coding:utf-8 # Purpose: Export 3D objects, build of faces with 3 or 4 vertices, as ASCII or Binary STL file. # License: MIT License import struct from tvtk.api import tvtk from mayavi import mlab from math import * from sympy import * ASCII_FACET = """facet normal 0 0 0 outer loop vertex {face[0][0]:.4f} {face[0][1]:.4f} {face[0][2]:.4f} vertex {face[1][0]:.4f} {face[1][1]:.4f} {face[1][2]:.4f} vertex {face[2][0]:.4f} {face[2][1]:.4f} {face[2][2]:.4f} endloop endfacet """ BINARY_HEADER ="80sI" BINARY_FACET = "12fH" class ASCII_STL_Writer: """ Export 3D objects build of 3 or 4 vertices as ASCII STL file. """ def __init__(self, stream): self.fp = stream self._write_header() def _write_header(self): self.fp.write("solid python\n") def close(self): self.fp.write("endsolid python\n") def _write(self, face): self.fp.write(ASCII_FACET.format(face=face)) def _split(self, face): p1, p2, p3, p4 = face return (p1, p2, p3), (p3, p4, p1) def add_face(self, face): """ Add one face with 3 or 4 vertices. """ if len(face) == 4: face1, face2 = self._split(face) self._write(face1) self._write(face2) elif len(face) == 3: self._write(face) else: raise ValueError('only 3 or 4 vertices for each face') def add_faces(self, faces): """ Add many faces. """ for face in faces: self.add_face(face) class Binary_STL_Writer(ASCII_STL_Writer): """ Export 3D objects build of 3 or 4 vertices as binary STL file. """ def __init__(self, stream): self.counter = 0 super(Binary_STL_Writer, self).__init__(stream) def close(self): self._write_header() def _write_header(self): self.fp.seek(0) self.fp.write(struct.pack(BINARY_HEADER, b'Python Binary STL Writer', self.counter)) def _write(self, face): self.counter += 1 data = [ 0., 0., 0., face[0][0], face[0][1], face[0][2], face[1][0], face[1][1], face[1][2], face[2][0], face[2][1], face[2][2], 0 ] self.fp.write(struct.pack(BINARY_FACET, *data)) def example(fn): def get_cube(): p=[] nxy=24 nz=21#Must be odd unit=10 h=2*unit dh=h/nz zbottom=-2*dh thickness=0.3*unit z=Symbol('z') f=1*(1+sin((z/h)**2*1*pi)/8)*exp(z/h/2)*unit#1* #f=(1+z/h)*unit flambdified = lambdify(z, f) fdiff=f.diff(z) fdifflambdified = lambdify(z, fdiff) rinner0=10 rinner=rinner0 router0=rinner0+thickness router=router0 deltar=1 deltaphi=2*pi/nxy deltaphih=deltaphi/2 nxyz=nxy*nz npts=0 #Inner: for j in range(0,nz+1): zact=j*dh ract=flambdified(zact) phiact=j%2*(-deltaphih) for i in range(0,nxy): p.append((ract*cos(phiact),ract*sin(phiact),zact)) phiact=phiact+deltaphi npts=npts+1 npts1=npts #Middle of upper rim: phiact=0 ract=flambdified(zact) a=fdifflambdified(zact) b=sqrt(1+a*a) k=thickness/b/2 for i in range(0,nxy): cosphi=cos(phiact) sinphi=sin(phiact) dx=k*cosphi dy=k*sinphi dz=-k*a p.append((ract*cosphi+dx,ract*sinphi+dy,zact+dz)) phiact=phiact+deltaphi npts1=npts1+1 #Outer: for j in range(-1,nz+2): zact=(nz-j-1)*dh ract=flambdified(zact) a=fdifflambdified(zact) b=sqrt(1+a*a) k=thickness/b phiact=(j-0)%2*(-deltaphih) for i in range(0,nxy): cosphi=cos(phiact) sinphi=sin(phiact) dx=k*cosphi dy=k*sinphi dz=-k*a p.append((ract*cosphi+dx,ract*sinphi+dy,zact+dz)) phiact=phiact+deltaphi npts1=npts1+1 #Center of bottom: p.append((0,0,-thickness)) parray=[] #Inner: for j in range(0,nz*2+4,2): for i in range(0,nxy): i0=i%nxy+j*nxy i1=(i+1)%nxy+j*nxy i2=(i+1)%nxy+nxy+j*nxy i3=i%nxy+nxy+j*nxy parray.append([p[i0],p[i1],p[i2],p[i3]]) for i in range(0,nxy): i0=(i+1)%nxy+nxy+j*nxy i1=i%nxy+nxy+j*nxy i2=i%nxy+nxy+nxy+j*nxy i3=(i+1)%nxy+nxy+nxy+j*nxy parray.append([p[i0],p[i1],p[i2],p[i3]]) #Inner bottom: for i in range(0,nxy): parray.append([(0,0,0),p[i%nxy],p[(i+1)%nxy]]) #Outer bottom: for i in range(0,nxy): parray.append([(0,0,zbottom),p[npts1-i%nxy-1],p[npts1-(i+1)%nxy-1]]) return parray filename=fn+'.stl' with open(filename, 'wb') as fp: writer = Binary_STL_Writer(fp) writer.add_faces(get_cube()) writer.close() print(filename,' saved.') # Finally the plotting: print('Finally the plotting....') stlr = tvtk.STLReader() stlr.file_name = file_name=filename stlr.update() stld = stlr.output fig = mlab.figure(bgcolor=(1, 1, 1), fgcolor=(0, 0, 0)) surf = mlab.pipeline.surface(stld, opacity=1, color=(0.3, 0.8, 0.7)) edge = mlab.pipeline.extract_edges(surf) edge_surf = mlab.pipeline.surface(edge, opacity=.1, color=(1,0,0)) if __name__ == '__main__': example('vase_simple') -- https://mail.python.org/mailman/listinfo/python-list