以下是代码:
import math
with open("test.stl") as file:
vertices = [map(float, line.split()[1:4])
for line in file
if line.lstrip().startswith('vertex')]
normals = [map(float, line.split()[2:5])
for line in file
if line.lstrip().startswith('facet')]
V=len(vertices)
ordering=[]
N=len(normals)
for i in range(0,N):
p1=vertices[3*i]
p2=vertices[3*i+1]
p3=verticies[3*i+2]
print p1
x1=p1[0]
y1=p1[1]
z1=p1[2]
x2=p2[0]
y2=p2[1]
z2=p2[2]
x3=p3[0]
y3=p3[1]
z3=p3[2]
a=[x2-x1,y2-y1,z2-z1]
b=[x3-x1,y3-y1,z3-z1]
a1=x2-x1
a2=y2-y1
a3=z2-z1
b1=x3-x1
b2=y3-y1
b3=z3-z1
normal=normals[i]
cross_vector=[a2*b3-a3*b2,a3*b1-a1*b3,a1*b2-a2*b1]
if cross_vector==normal:
ordering.append([i,i+1,i+2])
else:
ordering.append([i,i+2,i+1])
print ordering
print cross_vector
如果我尝试在for循环中添加print p1(或任何其他变量,如cross_vector),则没有任何错误但没有输出,如果我尝试在for循环之外打印它们,它说NameError:未定义名称'(变量名称)'。因此,如果没有定义这些变量,显然我的排序数组打印为[](空白)。我怎么能改变这个。变量是否必须在定义之前声明?
编辑:以下是运行上述代码时的错误输出:
Traceback (most recent call last):
File "convert.py", line 52, in <module>
print cross_vector
NameError: name 'cross_vector' is not defined
如上所述,这发生在for循环中定义的任何变量,我只是使用cross_vector作为示例。
答案 0 :(得分:6)
这一行:
vertices = [map(float, line.split()[1:4])
for line in file
if line.lstrip().startswith('vertex')]
读取文件中的所有行。在那之后,你就在文件的末尾,没有什么可读的了。所以
normals = [map(float, line.split()[2:5])
for line in file
if line.lstrip().startswith('facet')]
为空(normals == []
)。因此
N=len(normals)
将N
设置为0,表示此循环:
for i in range(0,N):
永远不会执行。这就是为什么从里面打印什么都不做的原因 - 循环没有运行。
答案 1 :(得分:3)
要解决DSM诊断出的问题,请使用:
import math
import itertools
with open("test.stl") as file:
i1, i2 = itertools.tee(file)
vertices = [map(float, line.split()[1:4])
for line in i1
if line.lstrip().startswith('vertex')]
normals = [map(float, line.split()[2:5])
for line in i2
if line.lstrip().startswith('facet')]
您可能还想尝试删除列表推导,并在整个过程中使用迭代器,以节省大文件的内存。
目前,您将整个文件加载到内存中,然后在内存中再创建两个完整大小的列表。相反,您可以按照只需要从内存中的文件读取的方式编写它。例如,我们可以用 generator comprehensions替换列表推导:
import math
import itertools
with open("test.stl") as file:
i1, i2 = itertools.tee(file)
vertexIter = (map(float, line.split()[1:4])
for line in i1
if line.lstrip().startswith('vertex'))
normalIter = (map(float, line.split()[2:5])
for line in i2
if line.lstrip().startswith('facet'))
在这里,我们完全避免使用任何内存。
要使其有用,您需要能够从以下位置替换循环:
for i in range(0,N):
p1=vertices[3*i]
p2=vertices[3*i+1]
p3=verticies[3*i+2]
normal = normals[i]
# processing
到单个迭代器:
for normal, p1, p2, p3 in myMagicIterator:
# processing
我能想到的一种方法是:
myMagicIterator = itertools.izip(
normalIter,
itertools.islice(vertexIter, 0, 3),
itertools.islice(vertexIter, 1, 3),
itertools.islice(vertexIter, 2, 3)
)
迭代器等效于:
myNormalList = zip(normals, vertices[0::3], vertices[1::3], vertices[2::3])
答案 2 :(得分:0)
在它之外声明它们(在for循环之前)并看看会发生什么。即使在for循环中声明它们也没关系,但是当循环不运行时,你可能希望它们具有“默认”值。
如果需要,请尝试发布很多较小的示例。