Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/firebase/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:解析二进制stl文件_Python_Binaryfiles - Fatal编程技术网

Python:解析二进制stl文件

Python:解析二进制stl文件,python,binaryfiles,Python,Binaryfiles,我在用Python(2.7.1 32位和Windows7 64)解析二进制STL文件时遇到一些困难。文件大小约为450k,但我的解析器在解析~8600个三角形中的244个三角形后突然停止工作,除了struct.unpack: 异常解包需要长度为12的字符串参数 文件中的光标位置是第33行,第929行。但该行包含大约3400个字符。所以这似乎不是新线问题 代码如下: import struct normals = [] points = [] triangles = [] bytecount =

我在用Python(2.7.1 32位和Windows7 64)解析二进制STL文件时遇到一些困难。文件大小约为450k,但我的解析器在解析~8600个三角形中的244个三角形后突然停止工作,除了struct.unpack:

异常解包需要长度为12的字符串参数

文件中的光标位置是第33行,第929行。但该行包含大约3400个字符。所以这似乎不是新线问题

代码如下:

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()
导入结构
法线=[]
点数=[]
三角形=[]
字节数=[]
fb=[]调试列表
def拆包(f、sig、l):
s=f.读数(l)
附页
返回结构解包(sig,s)
def read_三角形(f):

n=unpack(f),您的unpack函数调用了
f.read
两次。我怀疑您已经离开了文件的末尾

在Windows上以文本模式读取文件时也会遇到问题。
\r\n
的任何偶发事件都将作为
\n
读入。请进行以下更改以避免此问题

f = open(infilename, "rb")

你是对的,但这对我来说是个c&p错误。我会编辑代码。即使读两次数据,我应该能够解析8000个三角形中的4000个,而不是250个。第二部分起作用了,我没有以二进制模式打开文件。非常感谢。很高兴听到你这么说!我挠头了,然后我记得在Windows中,a^Z(ASCII 27)在流中被解释为EOF。你一定很早就找到了一个。然后我推荐这个很难找到的wikipedia页面。它不是一个好的文件格式,但几乎每个3D查看器软件或可视化工具包都知道并处理它,这导致了广泛的分发。你能解释一下你在哪里调用f.read()吗两次?是在read_length函数中吗?还是您已经编辑了以前的代码。我试过运行此函数,但得到了相同的错误我想我已经编辑了代码,请参阅日志以了解我的问题的更改。我的问题的答案是Marcelo Cantos回复的第二部分,我的原始代码以ascii打开文件并找到了eof很早就出现了。如果你以二进制模式打开它(见下面的答案),它就可以工作了。