0

这是代码:

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: name “(变量名)”未定义。因此,如果没有定义这些变量,显然我的排序数组打印为 [](空白)。我该如何改变这一点。变量必须在定义之前声明吗?

编辑:这是运行上述代码时的错误输出:

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 作为示例。

4

3 回答 3

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):

永远不会被执行。这就是为什么从内部打印什么都不做的原因——循环没有运行。

于 2013-01-13T20:24:43.230 回答
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')]

您可能还想尝试删除列表推导,并在整个过程中使用迭代器,以节省大文件的内存。


编辑:

目前,您将整个文件加载到内存中,然后在内存中再创建两个完整大小的列表。相反,您可以以仅根据需要从内存中的文件读取的方式编写它。例如,我们可以用生成器推导替换列表推导:

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])
于 2013-01-13T20:27:17.320 回答
0

在它之外(在 for 循环之前)声明它们,看看会发生什么。即使可以在 for 循环中声明它们,您也可能希望在循环不运行时拥有它们的“默认”值。

如有必要,请尝试发布一个更小的示例。

于 2013-01-13T20:25:05.347 回答