1. .off 、.obj 文件格式说明
这两种类型的文件都是文本文件,使用文本编辑工具即可打开,并查看里面的数据,每一行都是一个点或者一个面片。
.off 文件格式说明
以有一个 .off文件为例说明:
OFF
1658 2996 0
10.090349 4.409082 5.636783
10.120349 4.262582 5.613983
10.117149 4.390882 5.734783
10.117149 4.390882 5.734783
10.120349 4.262582 5.613983
10.090349 4.409082 5.636783
…
3 331 323 373
3 348 374 324
3 325 375 349
3 348 298 376
3 377 299 349
3 370 350 320
3 321 351 371
3 376 298 350
3 351 299 377
…
.off文件以OFF开头,下一行说明模型的顶点数量、面片的数量、边的数量(边的数量可以省略,一般都是0)
接下来的每一行数据就是描述一个顶点或者一个面片
描述顶点的行列出这个点的x, y, z坐标;
描述面片的行列出构成面片的顶点的数量、各个顶点的索引列表(该索引即该顶点在文件中的第几个顶点,注意:.off 文件中顶点的索引是从0开始的!)
根据.off 文件的构成可以知道 .off 文件中只存储了点以及构成面片的点,所以将.obj 文件转化为.off 文件时只需要取出其中的点和面片的信息即可!
.obj 文件格式说明
在 .obj 文件中关于点和面片的信息,其余的不做介绍。
描述顶点: v x坐标 y坐标 z坐标
v x y z
描述平面:
顶点坐标索引: f 顶点1 顶点2 …
f v1 v2 v3 …
顶点纹理坐标索引: f 顶点坐标索引/纹理坐标索引
f v1/vt1 v2/vt2 v3/vt3 …
顶点纹理法线坐标索引: f 顶点坐标索引/纹理坐标索引/法线索引
f v1/vt1/vn1 v2/vt2/vn2 …
顶点法线坐标索引(不包含纹理索引): f 顶点坐标索引//法线坐标索引
f v1//vn1 v2//vn2
注意:.obj文件中顶点的索引时从1开始的!
python代码实现,在实现的过程中参考了博客obj文件转off。但是修改了其中一部分。
def obj2off(objpath, offpath):
'''
将obj文件转换为off文件
:param objpath: .obj文件的路径
:param offpath: .off文件的路径的保存地址
:return: 无
'''
line = ""
vset = []
fset = []
with open(objpath,'r') as f:
lines = f.readlines()
p = re.compile(r'/+')
space = re.compile(r' +')
for line in lines:
#拿到obj文件中一行,作为一个字符串
tailMark = " "
line = line+tailMark
if line[0]!='v' and line[0]!='f' :
continue
parameters = space.split(line.strip())
if parameters[0] == "v": #如果是顶点的话
Point = []
Point.append(eval( parameters[1]) )
Point.append(eval( parameters[2]) )
Point.append(eval( parameters[3]) )
vset.append(Point)
elif parameters[0] == "f": #如果是面的话,存放顶点的索引
vIndexSets = [] #临时存放点的集合
for i in range(1,len(parameters) ):
x = parameters[i]
ans = p.split(x)[0]
index = eval(ans)
index -= 1 #因为顶点索引在obj文件中是从1开始的,而我们存放的顶点是从0开始的,因此要减1
vIndexSets.append(index)
fset.append(vIndexSets)
with open(offpath, 'w') as out:
out = open(offpath, 'w')
out.write("OFF\n")
out.write(str(vset.__len__()) + " " + str(fset.__len__()) + " 0\n")
for j in range(len(vset)):
out.write(str(vset[j][0]) + " " + str(vset[j][1]) + " " + str(vset[j][2]) + "\n")
for i in range(len(fset)):
s = str(len( fset[i] ))
for j in range( len( fset[i] ) ):
s = s+ " "+ str(fset[i][j])
s += "\n"
out.write(s)
print("{} 转换成 {} 成功!".format( p.split(objpath)[-1], p.split(offpath)[-1] ))
如果有需要.obj模型文件或者.off模型文件的可以留言!