.obj 文件中的面孔是什么以及它们如何工作?
What are faces in .obj files and how do they work?
我有 this.obj 文件。这是一个Mini-Cooper的模型。我将所有顶点和面提取到如下所示的列表中:
vertices = [(14.82, -22.56, 25.83), (25.38, 29.02, 15.87), (-31.71, -57.05, 19.29), (-27.95, 46.76, 17.98), (-25.44, 47.58, 3.38), (33.63, 48.57, 7.97), (-30.81, 32.23, 22.08), (-14.13, 29.34, 27.43), (3.94, 47.76, 52.66), (25.38, -69.78, 16.93), (29.55, 4.96, 38.49), (33.31, 42.57, 13.42), (27.8, 8.16, 38.6), (-26.77, 46.93, 2.27), (-30.21, -80.45, 24.88), (-33.48, 40.09, 23.68), (33.29, 51.84, 13.67), (-9.08, 67.39, 17.91), (25.27, 31.68, 5.62), (-30.2, -36.77, 39.17)]
faces = [('1962/1/1962', '1958/1/1958', '1957/541/1957'), ('1957/541/1957', '1961/541/1961', '1962/1/1962'), ('1960/3202/1960', '1959/542/1959', '1963/542/1963'), ('1963/542/1963', '1964/3202/1964', '1960/3202/1960'), ('1966/543/1966', '1962/1/1962', '1961/541/1961'), ('1961/541/1961', '1965/544/1965', '1966/543/1966'), ('1964/3202/1964', '1963/542/1963', '1967/546/1967'), ('1967/546/1967', '1968/545/1968', '1964/3202/1964'), ('1970/543/1970', '1966/543/1966', '1965/544/1965'), ('1965/544/1965', '1969/544/1969', '1970/543/1970'), ('1968/545/1968', '1967/546/1967', '1971/546/1971'), ('1971/546/1971', '1972/545/1972', '1968/545/1968'), ('1985/547/1985', '1970/543/1970', '1969/544/1969'), ('1969/544/1969', '1984/550/1984', '1985/547/1985'), ('1993/551/1993', '1961/541/1961', '1957/541/1957'), ('1957/541/1957', '1991/551/1991', '1993/551/1993'), ('1958/1/1958', '1962/1/1962', '1994/548/1994'), ('1994/548/1994', '1992/548/1992', '1958/1/1958'), ('1965/544/1965', '1961/541/1961', '1993/551/1993'), ('1993/551/1993', '1995/550/1995', '1965/544/1965')]
这些只是前 20 个。我写了一个渲染程序,当我输入顶点时,它显示了这个:
它看起来像 top-down 汽车视图,这是有道理的。我是 3d 模型的初学者。如何添加面孔?我的程序可以从 3 个点画出三角形,但是面的数量很大,所以不能只是坐标。它们是什么以及如何从中获取三角形?
我想用一些代码来扩展我的评论,这些代码展示了如何解析一些文件,然后用顶点索引替换实际坐标:
def main():
import re
flt = r"-?[\d\.]+"
vertex_pattern = r"v\s+(?P<x>{})\s+(?P<y>{})\s+(?P<z>{})".format(flt, flt, flt)
face_pattern = r"f\s+((\d+/\d+/\d+\s*){3,})"
vertices = []
faces = []
with open("alfa147.obj.txt", "r") as file:
for line in map(str.strip, file):
match = re.match(vertex_pattern, line)
if match is not None:
vertices.append(tuple(map(float, match.group("x", "y", "z"))))
continue
match = re.match(face_pattern, line)
if match is not None:
faces.append(tuple(tuple(map(int, vertex.split("/"))) for vertex in match.group(1).split()))
print(f"The first face has {len(faces[0])} vertices:")
for vertex in faces[0]:
print(vertex)
print("\nWe do not care about the texture coordinate indices or normal indices, so we get the three vertex indices:")
for vertex in faces[0]:
print(vertex[0])
print("\nAfter substituting the indices for their values, the face is made up of these coordinates:")
for vertex in faces[0]:
print(vertices[vertex[0]-1]) # -1 because in the OBJ spec, collections start at index 1 rather than 0
return 0
if __name__ == "__main__":
import sys
sys.exit(main())
输出:
The first face has 3 vertices:
(1962, 1, 1962)
(1958, 1, 1958)
(1957, 541, 1957)
We do not care about the texture coordinate indices or normal indices, so we get the three vertex indices:
1962
1958
1957
After substituting the indices for their values, the face is made up of these coordinates:
(-4.29133, 47.755795, 51.585678)
(-4.29133, 47.716423, 51.585678)
(-4.29133, 47.716423, 52.661789)
>>>
我有 this.obj 文件。这是一个Mini-Cooper的模型。我将所有顶点和面提取到如下所示的列表中:
vertices = [(14.82, -22.56, 25.83), (25.38, 29.02, 15.87), (-31.71, -57.05, 19.29), (-27.95, 46.76, 17.98), (-25.44, 47.58, 3.38), (33.63, 48.57, 7.97), (-30.81, 32.23, 22.08), (-14.13, 29.34, 27.43), (3.94, 47.76, 52.66), (25.38, -69.78, 16.93), (29.55, 4.96, 38.49), (33.31, 42.57, 13.42), (27.8, 8.16, 38.6), (-26.77, 46.93, 2.27), (-30.21, -80.45, 24.88), (-33.48, 40.09, 23.68), (33.29, 51.84, 13.67), (-9.08, 67.39, 17.91), (25.27, 31.68, 5.62), (-30.2, -36.77, 39.17)]
faces = [('1962/1/1962', '1958/1/1958', '1957/541/1957'), ('1957/541/1957', '1961/541/1961', '1962/1/1962'), ('1960/3202/1960', '1959/542/1959', '1963/542/1963'), ('1963/542/1963', '1964/3202/1964', '1960/3202/1960'), ('1966/543/1966', '1962/1/1962', '1961/541/1961'), ('1961/541/1961', '1965/544/1965', '1966/543/1966'), ('1964/3202/1964', '1963/542/1963', '1967/546/1967'), ('1967/546/1967', '1968/545/1968', '1964/3202/1964'), ('1970/543/1970', '1966/543/1966', '1965/544/1965'), ('1965/544/1965', '1969/544/1969', '1970/543/1970'), ('1968/545/1968', '1967/546/1967', '1971/546/1971'), ('1971/546/1971', '1972/545/1972', '1968/545/1968'), ('1985/547/1985', '1970/543/1970', '1969/544/1969'), ('1969/544/1969', '1984/550/1984', '1985/547/1985'), ('1993/551/1993', '1961/541/1961', '1957/541/1957'), ('1957/541/1957', '1991/551/1991', '1993/551/1993'), ('1958/1/1958', '1962/1/1962', '1994/548/1994'), ('1994/548/1994', '1992/548/1992', '1958/1/1958'), ('1965/544/1965', '1961/541/1961', '1993/551/1993'), ('1993/551/1993', '1995/550/1995', '1965/544/1965')]
这些只是前 20 个。我写了一个渲染程序,当我输入顶点时,它显示了这个:
它看起来像 top-down 汽车视图,这是有道理的。我是 3d 模型的初学者。如何添加面孔?我的程序可以从 3 个点画出三角形,但是面的数量很大,所以不能只是坐标。它们是什么以及如何从中获取三角形?
我想用一些代码来扩展我的评论,这些代码展示了如何解析一些文件,然后用顶点索引替换实际坐标:
def main():
import re
flt = r"-?[\d\.]+"
vertex_pattern = r"v\s+(?P<x>{})\s+(?P<y>{})\s+(?P<z>{})".format(flt, flt, flt)
face_pattern = r"f\s+((\d+/\d+/\d+\s*){3,})"
vertices = []
faces = []
with open("alfa147.obj.txt", "r") as file:
for line in map(str.strip, file):
match = re.match(vertex_pattern, line)
if match is not None:
vertices.append(tuple(map(float, match.group("x", "y", "z"))))
continue
match = re.match(face_pattern, line)
if match is not None:
faces.append(tuple(tuple(map(int, vertex.split("/"))) for vertex in match.group(1).split()))
print(f"The first face has {len(faces[0])} vertices:")
for vertex in faces[0]:
print(vertex)
print("\nWe do not care about the texture coordinate indices or normal indices, so we get the three vertex indices:")
for vertex in faces[0]:
print(vertex[0])
print("\nAfter substituting the indices for their values, the face is made up of these coordinates:")
for vertex in faces[0]:
print(vertices[vertex[0]-1]) # -1 because in the OBJ spec, collections start at index 1 rather than 0
return 0
if __name__ == "__main__":
import sys
sys.exit(main())
输出:
The first face has 3 vertices:
(1962, 1, 1962)
(1958, 1, 1958)
(1957, 541, 1957)
We do not care about the texture coordinate indices or normal indices, so we get the three vertex indices:
1962
1958
1957
After substituting the indices for their values, the face is made up of these coordinates:
(-4.29133, 47.755795, 51.585678)
(-4.29133, 47.716423, 51.585678)
(-4.29133, 47.716423, 52.661789)
>>>