开发者

Python: parsing binary stl file

开发者 https://www.devze.com 2023-04-08 04:22 出处:网络
I\'m having some difficulties while parsing a binary STL file with Python (2.7.1 32-bit and Wind开发者_开发问答ows 7 64). The file is a about 450k in size, but my parser suddenly stops working after p

I'm having some difficulties while parsing a binary STL file with Python (2.7.1 32-bit and Wind开发者_开发问答ows 7 64). The file is a about 450k in size, but my parser suddenly stops working after parsing 244 triangles out of ~8600 with en exception of struct.unpack:

Exception unpack requires a string argument of length 12

The cursor position in the file is line 33, row 929. But the line contains about 3400 characters. So it doesn't seem to be newline problem.

This is the code:

import struct

normals = []
points = []
triangles = []
bytecount = []

fb = [] # debug list

def unpack (f, sig, l):
    s = f.read (l)
    fb.append(s)
    return struct.unpack(sig, s)

def read_triangle(f):
    n = unpack(f,"<3f", 12)
    p1 = unpack(f,"<3f", 12)
    p2 = unpack(f,"<3f", 12)
    p3 = unpack(f,"<3f", 12)
    b = unpack(f,"<h", 2)

    normals.append(n)
    l = len(points)
    points.append(p1)
    points.append(p2)
    points.append(p3)
    triangles.append((l, l+1, l+2))
    bytecount.append(b[0])


def read_length(f):
    length = struct.unpack("@i", f.read(4))
    return length[0]

def read_header(f):
    f.seek(f.tell()+80)

def write_as_ascii(outfilename):
    f = open(outfilename, "w")
    f.write ("solid "+outfilename+"\n")
    for n  in range(len(triangles)):
        f.write ("facet normal {} {} {}\n".format(normals[n][0],normals[n][1],normals[n][2]))
        f.write ("outer loop\n")
        f.write ("vertex {} {} {}\n".format(points[triangles[n][0]][0],points[triangles[n][0]][1],points[triangles[n][0]][2]))
        f.write ("vertex {} {} {}\n".format(points[triangles[n][1]][0],points[triangles[n][1]][1],points[triangles[n][1]][2]))
        f.write ("vertex {} {} {}\n".format(points[triangles[n][2]][0],points[triangles[n][2]][1],points[triangles[n][2]][2]))
        f.write ("endloop\n")
        f.write ("endfacet\n")
    f.write ("endsolid "+outfilename+"\n")
    f.close()

def main():
    infilename = r"cupHemis46_28.stl"
    outfilename = r"cupHemis46_28_ascii_test.stl"

    try:
        f = open ( infilename, "r")

        read_header(f)
        l = read_length(f)
        try:
            while True:
                read_triangle(f)
        except Exception, e:
            print "Exception",e[0]
        print len(normals), len(points), len(triangles), l
        write_as_ascii(outfilename)

    except Exception, e:
        print e


if __name__ == '__main__':
    main()

The unpack function (not from struct) collects all the strings which will be written to a file. When I compare both file they seem equal, up to the file position where unpack stops working. I opened the binary file with Notepad++, the next character is a "SUB".

Are there any restrictions of unpack that I'm not aware of regarding file size or limitation in characters or something? Is there something wrong with my code? Thanks in advance.


Your unpack function calls f.read twice. I suspect you've walked off the end of the file.

You'll also have trouble with reading the file in text mode on Windows. Any incidental occurrences of \r\n will be read in as \n. Make the following change to avoid this problem.

f = open(infilename, "rb")
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号