obj格式是什么,obj文件转换

  obj格式是什么,obj文件转换

  前言最近在处理一些网格渲染的时候,需要对Obj文件进行分析。我从Free3D上随机找了一个免费的人体obj模型分析测试波。

  国际惯例,参考博客:

  本文使用的模型是从Free3D下载的。obj文件格式和。mtl文件格式

  详细解释一下3D中的obj文件格式。

  三维OBJ文件格式分析

  对象文件解析

  维基百科波前。对象文件

  目标文件(。obj)

  MTL文件OBJ文件的材料定义

  Python读取对象

  obj的可视化软件MeshLab

  文件结构【注意】各种obj文件可能不一样,但是包含的字段含义都是一样的。只要核对一下数字就能理解它们的意思。如果有任何字段没有在注释中描述,这意味着它们不常用。自己查阅相关文献。

  以下载到简单格式obj为例:

  #用于注释

  Mtllib mtllib:代表素材库,通常指向一个mtl文件。

  # 3ds max wave front obj exporter v 0.97 b-(c)2007 guru ware # : 05 . 11 . 2019 15:52:38 new MTL 091 _ w _ aya _ 2k _ 01ns 30.000 ni 1.5000d 1.0000 tr 0.0000 1.0000 ks 0.0000 0.0000 0 0.0000 ke 0.0000 0 0.0000 map _ 1

  其他字段通常包含在obj next中:

  v(顶点):几何形状的顶点。因为物体是由面组成的,而面是由线组成的,线是由点组成的,所以不管是什么形状,都必然有一个几何顶点;一些应用程序支持顶点颜色,这些颜色通过在x y z后面跟随红色、绿色、蓝色的值来表示。颜色的范围是0到1.0。

  #几何顶点列表,坐标为(x,y,z [,w]),w可选,默认为1.0.v0.123 0.234 0.345 1.0v.vt(顶点纹理):顶点纹理,它表示纹理贴图的哪个像素对应当前顶点,通常为0-1。如果大于1,相当于重新展开纹理然后取值,比如镜像填充和翻转填充,然后根据纹理图的宽度和高度计算具体的像素位置。

  #纹理坐标列表,在(u,[,v,w])坐标中,这些将在0和1之间变化。v是可选的,默认为0.vt 0.500 1 [0] vt.VN(顶点法线):物理学上说眼睛看到物体是因为光从物体表面反射到眼睛,所以这个法线就是用来计算反射光通过入射光的法线。

  #以(x,y,z)形式列出顶点法线;法线可能不是单位向量.f (face):大部分几何体都包含人脸,除非像发束这样的模型只包含单根头发的顶点,而且大部分模型的头发也是用面片的方法渲染的。常见的曲面是由三个顶点组成的三角形曲面,当然也有多边形,但我很少见到。其格式有几种形式:

  只有顶点f v1 v2 v3.顶点和纹理f v1/vt1 v2/vt2 v3/vt3.顶点纹理和法线FV1/VT1/VN1V2/VT2/VN2V3/VN3.包括顶点和法向f v1//vn1 v2//vn2 v3//vn3.o,G,

  091 _ w _ Aya _ 100k _ 01g 091 _ w _ Aya _ 100k _ 01使用MTL091 _ w _ Aya _ 2k _ 01s off其中:

  Usemtl指定模型的材质O:表示对象,表示不同的对象名称G:表示组、顶点或三角形面片集名称S:表示平滑。不同的记录方式用斜线来区分不同的字段索引,F后面跟一个正整数,代表对应字段的索引。

  #多边形面元素(见下文)f1 23 F3/1 4/2 5/3 F6/4/1 3/5/3 7/6/5f 7/1 8/2 9//3f.很好理解,每个顶点代表空间中的一个位置,可以给他一个颜色,这个位置也可以有一个法线。

  【注意】其实除了顶点发现,一些非obj模型文件也定义了曲面法线,比如VRay渲染软件。

  PRNet在代码显示前的人脸重建和这个很像。读取顶点V的三维坐标后,通过vt将二维纹理图映射到每个顶点。通过曲面着色,一个曲面有三个顶点,可以通过这三个顶点计算出正面颜色。

  按照读文件的方法逐行读取obj,然后通过正则表达式找到v,vt,vn,f

  filename= 091 _ W _ Aya _ 10k。obj vertices=[]vertex _ norm=[]vertex _ tex=[]triangles=[]tex coords=[]for line in open(filename, r ):values=line。split()if(values==[]):continue if(values== # ):continue if(values[0]= v ):顶点。append([float(values[1])),float(values[2])),float(values[3]))if(values[0]= VN ):vertex _ if因为索引都是从一开始,而大蟒等语言的数组通常从0开始,所以需要将索引-1

  顶点=np.array(顶点,np.int32)顶点=顶点-np.min(顶点)顶点[.1]=np.max(顶点数[.1]) -顶点[.1]三角形=np.array(三角形,np。int)-1特克斯帘线=NP。数组(tex coords,NP。int)-1 vertex _ tex=NP。数组(vertex _ tex,np.float32)接下来纹理图:

  uv_map=plt.imread( ./tex/091 _ W _ Aya _ 2K _ 01。jpg )uv _ map=uv _ map。astype( float 32 )uv _ map=NP。rot 90(uv _ map,3)最后一行旋转图片的原因是,工厂读取的图像像素坐标和目标文件存储的坐标顺序有这样的一个关系。

  最终,使用中文版画三角面,每个三角面的颜色为三个顶点对应颜色的平均值

  img _ 3D=NP。零((NP。最大(顶点[.1]),np.max(顶点[.0]),3),dtype=NP。uint 8)表示范围内的I(三角形。shape[0]):CNT=NP。数组([(顶点[三角形[i,0],0],顶点[三角形[i,0],1])),(顶点[三角形[i,1],0],顶点[三角形[i,1],1])),(顶点[三角形[i,2],0),顶点[三角形[i,2],1])],dtype=NP。int 32)color _ coord 1 _ x=int.] uv_map[color_coord2_x,color_coord2_y,]uv _ map[颜色坐标3_x,颜色坐标3_y.])/3.0 img _ 3D=cv2。绘制等高线(img _ 3D,[cnt],0,(int(color[0]),int(color[1]),int(color[2])),-1)PLT。fig(figsize=(16,16))PLT。im show(img _ 3D/255.0)PLT。轴(“关”)对比一下与网格实验室可视化结果

  为什么会出现这种情况,感觉有些纹理不对,原因在于我们做中文版可视化的时候,并没有区分先渲染前面还是先渲染后面,而是按照目标文件存储的三角面顺序着色,所以导致了图里面有些背面覆盖了前面,出现这种一块一块的不对劲效果,其实异常块是模型不可见部分的颜色而已。有兴趣可自行优化一下渲染算法,区分一下背面和正面。

  ——————2020.12.30更——————

  纹理贴图完整版请看:OBJ可视化——UV还原(修正)

  后记分析一下目标文件格式的三维(三维的缩写)模型文件的各个字段原理,同时进行简单的可视化测试

  

完整的python脚本实现放在微信公众号的简介中描述的github中

,有兴趣可以去找找,同时文章也同步到微信公众号中,有疑问或者兴趣欢迎公众号私信。

obj格式是什么,obj文件转换