####################################### # stl.py - for Blender STL exporting # # By Chris Want using code pinched # # from Jan Walter's POV export script # ####################################### import Blender from math import sqrt from struct import pack # *** note *** # Must specify an object name for blender 2.10 or later. # For blender 2.04 or earlier the select mesh gets exported meshObjectName = "Plane" # STL has two subformats: a binary one that is # used if exportFormat = "Binary" or a text format # that is used otherwise exportFormat = "Text" class StlExport: def __init__(self,name,format): self.file = None self.numFaces = 0 if self.NMeshQuery(): self.object = Blender.Object.GetSelected()[0] self.name = self.object.data.name self.writeData = self.writeDataOldApi else: self.object = Blender.getObject(name) self.name = name self.writeData = self.writeDataNewApi if format == "Binary": self.writeHead = self.writeHeadBinary self.writeFace = self.writeFaceBinary self.writeTail = self.writeTailBinary self.writemode = "wb" else: self.writeHead = self.writeHeadText self.writeFace = self.writeFaceText self.writeTail = self.writeTailText self.writemode = "w" def export(self): if self.object=="None": print "Select a mesh object and try again" else: self.writeData() def writeDataOldApi(self): filename = self.name + ".stl" mesh = Blender.NMesh.GetRaw(self.name) print "exporting to file " + filename + " ..." self.file = open(filename, self.writemode) self.writeHead(self.name) for face in mesh.faces: self.writeFace(face.v[0].co,face.v[1].co,face.v[2].co) try: self.writeFace(face.v[0].co,face.v[2].co,face.v[3].co) except: pass self.writeTail() self.file.close() print "All done -- have a nice day!" def writeDataNewApi(self): filename = self.name + ".stl" if Blender.isMesh(self.name): print "exporting to file " + filename + " ..." self.file = open(filename, self.writemode) mesh = Blender.getMesh(self.object.data) self.writeHead(self.name) for face in mesh.faces: self.writeFace(mesh.vertices[face[0]],mesh.vertices[face[1]],mesh.vertices[face[2]]) if mesh.vertices[face[3]]: self.writeFace(mesh.vertices[face[0]],mesh.vertices[face[2]],mesh.vertices[face[3]]) self.writeTail() self.file.close() print "All done -- have a nice day!" else: print "Sorry can export meshes only ..." def writeHeadText(self,meshname): self.file.write("solid " + meshname + "\n") def writeHeadBinary(self,meshname): self.file.write("%-80.80s " % meshname) def writeFaceText(self,vert1,vert2,vert3): fNormal = self.getFaceNormal(vert1,vert2,vert3) self.file.write(" facet normal %f %f %f\n" % (fNormal[0],fNormal[1],fNormal[2])) self.file.write(" outer loop\n") self.file.write(" vertex %f %f %f\n" % (vert1[0],vert1[1],vert1[2])) self.file.write(" vertex %f %f %f\n" % (vert2[0],vert2[1],vert2[2])) self.file.write(" vertex %f %f %f\n" % (vert3[0],vert3[1],vert3[2])) self.file.write(" endloop\n") self.file.write(" endfacet\n") def writeFaceBinary(self,vert1,vert2,vert3): fNormal = self.getFaceNormal(vert1,vert2,vert3) self.file.write(pack("fff",fNormal[0],fNormal[1],fNormal[2])) self.file.write(pack("fff",vert1[0],vert1[1],vert1[2])) self.file.write(pack("fff",vert2[0],vert2[1],vert2[2])) self.file.write(pack("fff",vert3[0],vert3[1],vert3[2])) self.file.write(" ") self.numFaces=self.numFaces+1 def writeTailText(self): self.file.write("endsolid\n") def writeTailBinary(self): self.file.seek(80) self.file.write("%4.4s" % pack("L",self.numFaces)) def getFaceNormal(self,v1,v2,v3): a = [v2[0]-v1[0],v2[1]-v1[1],v2[2]-v1[2]] b = [v3[0]-v1[0],v3[1]-v1[1],v3[2]-v1[2]] n = [a[1]*b[2] - a[2]*b[1],a[2]*b[0]-a[0]*b[2],a[0]*b[1]-a[1]*b[0]] nlen = sqrt(n[0]**2+n[1]**2+n[2]**2) return [n[0]/nlen,n[1]/nlen,n[2]/nlen] def NMeshQuery(self): try: dir(Blender.NMesh) except: return 0 else: return 1 stlexport = StlExport(meshObjectName,exportFormat) stlexport.export()