# Name: stlascii2bin.py
# Author: James Blackwell
# Rev: 1.0 - 02Oct10 - Created
#
# Description:
# This script takes in an ASCII STL file and converts it to a binary
# version.
import sys, struct
# TODO:
def CheckASCIIFile(ip):
'''Check if the first word on this line is 'solid'. If not, it probably
isn't an ASCII STL file'''
if not ip.find('solid') == 0:
# Haven't found the keyword 'solid' on the first line.
# This isn't an ASCII STL file
print 'Error: This does not appear to be an ASCII STL file.'
return False
return True
def normal(line):
'''Take a line containing normals and convert to an array of floats'''
vals = line.split()[-3:]
norms = [float(n) for n in vals]
# print "%s %s %s" % (norms[0], norms[1], norms[2])
return norms
def vertex(line):
'''Take a line containing verticies and convert to an array of floats'''
vals = line.split()[-3:]
verts = [float(v) for v in vals]
# print "%s %s %s" % (verts[0], verts[1], verts[2])
return verts
def OutputHeader(op, ipfile, opfile):
'''Create the 80-byte header for the bin STL file'''
str = 'Converted from ASCII using stlascii2bin.py by James Blackwell. %s to %s' % (ipfile, opfile)
if len(str)>=80:
# Too long, strip some off.
str = str[:80]
else:
# Too short, pad it out.
str = str + (80-len(str))*' '
op.write(str)
def OutputNumTris(op, numTris):
'''Output the number of triangles in the file'''
op.write(struct.pack('<L', numTris))
def OutputTriangleData(op, triangles):
'''Output the triangle data (3xNorms, 3x3xVertex, 1xAtribCnt'''
for triangle in triangles:
for el in triangle:
op.write(struct.pack('<f', el))
op.write(struct.pack('<H', 0)) # Add Attribute Byte Count - Always zero
def PrintHelp():
print '''
This script converts an ASCII STL file to a binary one.
Useage:
python stlascii2bin.py <ipfile>
The script will convert the ipfile and generate a binary version with
the name '<ipfile>_bin.ext'.'''
def Main(ipfile):
triangles = []
# Open the input file or fail gracefully
try:
fh = open(ipfile, 'r')
except:
print '\n**Error: File "%s" not found**' % (ipfile)
PrintHelp()
return
print 'Converting input file: %s' % (ipfile)
firstLine = True
for line in fh:
if firstLine:
# Check first line to see if this is an ASCII STL file
firstLine = False
if not CheckASCIIFile(line):
return
# Strip any leading whitespace
line = line.strip()
# Handle Normals
if line.find("facet") == 0:
triangle = normal(line)
# Handle Vertexes
if line.find("vertex") != -1:
triangle += vertex(line)
# Finished collating triangle, add it to the list
if line.find('endfacet') == 0:
triangles.append(triangle)
fh.close()
print 'Found %s Triangles' % (len(triangles))
# Create output filename, open it or fail gracefully
name, ext = ipfile.split('.')
opfile = name+'_bin'+'.'+ext
try:
op = open(opfile, 'wb')
except:
print 'Error: Could not create output file %s' % (opfile)
return
# Output the data
print 'Generating output file: %s' % (opfile)
OutputHeader(op, ipfile, opfile)
OutputNumTris(op, len(triangles))
OutputTriangleData(op, triangles)
op.close()
print 'Conversion complete'
if __name__ == '__main__':
# Check the command line inputs
if len(sys.argv) != 2:
PrintHelp()
else:
Main(sys.argv[1])
No comments:
Post a Comment