在VTK 或者Opengl纹理贴图中都会用到模型文件,当使用vtkOBJImporter函数读取模型数据时,需要对应的MTL文件才能实现纹理贴图,但是网上大多数的OBJ文件和MTL文件都是由模型软件导出来的,也很少有写MTL文件的,本文记录如何用c++写能够直接被vtkOBJImporter函数读取的模型文件和材质文件。

OBJ文件的组成

  1. v:顶点坐标

  1. vn:顶点法向量

  1. Vt:纹理坐标

  1. usemtl mtl:使用的材质,与mtl文件相呼应;

  1. f:表示由顶点,法向量和纹理坐标所确定的面,如5/2/1表示 v开头的第5个顶点,这个点对应vn开头的第2个法向量,对应vt 贴图的第1个坐标;
    将之前读取的3D点云,法向量,纹理和网格数据导入到向量中,由于写入OBJ文件的数据一定要ASCII或者二进制格式的,因此再定义3D向量点用于存储读取的数据,,按OBJ文件的组成顺序将向量一一写入,完成OBJ文件。

string num = "1";
vector<Point3d> v1(a);
vector<Point3d> vt(a);
vector<Point3d> vn(b);
vector<Point3d> f(b);
vector<Point3d> vec(b);
float s1=0, s2=0, s3=0;
for (int i = 0; i < a; i++)
{v1[i].x = orig[i].x;v1[i].y = orig[i].y;v1[i].z = orig[i].z;
}for (int i = 0; i < a; i++)
{vt[i].x = uv[i].s;vt[i].y = uv[i].t;}float max=0,min=0;for (int i = 0; i < b; i++)
{vn[i].x = orn[i].x;vn[i].y = orn[i].y;vn[i].z = orn[i].z;s1 += orn[i].x;s2 += orn[i].y;s3 += orn[i].z;f[i].x = fi[i].x;f[i].y = fi[i].y;f[i].z = fi[i].z;vec[i].x = i + 1;if (max <= orn[i].x){max = orn[i].x;}if (min >= orn[i].x){min = orn[i].x;}
}std::cout << "MAX:MIN" << " " << max  << " " << min  << endl;
std::cout << "average X:Y:Z:" << " " << s1/b<<" "<< s2 / b << " " << s3 / b << " " << endl;ofstream OutFile(filename);
char c1[100] = "o blood.00";
for (int i = 0; c1[i] != 0; i++)//对字符逐个处理,直到遇到'/0'为止
{OutFile.put(c1[i]);}
OutFile << num.c_str() << endl;
for (int i = 0; i < a; i++)
{OutFile << "v " << setiosflags(ios::fixed) << setprecision(6) << v1[i].x << " " << v1[i].y << " " << v1[i].z << endl;}for (int i = 0; i < b; i++)
{OutFile << "vn " << setiosflags(ios::fixed) << setprecision(6) << vn[i].x << " " << vn[i].y << " " << vn[i].z << endl;}for (int i = 0; i < a; i++)
{OutFile << "vt " << setiosflags(ios::fixed) << setprecision(6) << vt[i].x << " " << vt[i].y << endl;}char c[100] = "usemtl mtl";
for (int i = 0; c[i] != 0; i++)//对字符逐个处理,直到遇到'/0'为止
{//if (c[i] >= 65 && c[i] <= 90 || c[i] >= 97 && c[i] <= 122)//如果是字母字符 OutFile.put(c[i]);}
OutFile << num.c_str() << endl;
char c2[100] = "s off\n";
for (int i = 0; c2[i] != 0; i++)//对字符逐个处理,直到遇到'/0'为止
{//if (c[i] >= 65 && c[i] <= 90 || c[i] >= 97 && c[i] <= 122)//如果是字母字符 OutFile.put(c2[i]);}for (int i = 0; i < b; i++)
{OutFile << "f " << setiosflags(ios::fixed) << setprecision(0) << f[i].x << "/" << f[i].x << "/" << vec[i].x << " " << f[i].y << "/" << f[i].y << "/" << vec[i].x << " " << f[i].z << "/" << f[i].z << "/" << vec[i].x << endl;
}OutFile.close();            //关闭文件std::cout << "写结束" << std::endl;

注意:orig,uv,orn,fi里面存储的分别是读取本地的3D点云,纹理坐标,法向量和网格数据。

MTL文件的组成

  1. newmtl mtl:定义材质为mtl,与obj文件中的usemtl mtl相呼应,一般不需要更改,若要更改,则要同时更改usemtl mtl。

  1. Ns表示高光色的权重,范围在0-1000

  1. Ka表示环境光,三个数字分别对应R、G、B值

  1. Kd表示漫反射光,三个数字分别对应R、G、B值

  1. Ks表示高光,三个数字分别对应R、G、B值

  1. Ke表示发射光,三个数字分别对应R、G、B值

  1. Ni表示光学密度

  1. d表示透明度,0是完全透明,1是完全不透明

  1. map_Kd 表示所需贴图照片的名称

  1. illum 2表示指定的光照模型(参考:Phong光照模型),illum后面的数字范围为0~10,具体含义如下:

0 :Color on and Ambient off

1 :Color on and Ambient on

2 :Highlight on

3 :Reflection on and Ray trace on

4 :Transparency: Glass on

Reflection: Ray trace on

5 :Reflection: Fresnel on and Ray trace on

6 :Transparency: Refraction on

Reflection: Fresnel off and Ray trace on

7 :Transparency: Refraction on

Reflection: Fresnel on and Ray trace on

8 :Reflection on and Ray trace off

9 :Transparency: Glass on

Reflection: Ray trace off

10 :Casts shadows onto invisible surfaces

MTL文件记录的是材质信息,也是ASCII格式的文件,必须有MTL文件才能实现贴图的效果,若没有此文件,则只会出来模型。在写文件时按照代码所示,根据照片的格式和名称更改框选的区域,例如照片名称为ABC_n.jpg,那么图中的“201_”要写成“ABC_”,“.png\n”改为“.jpg\n”

如果图片过亮或者过暗,可以根据上述参数进行更改,一般建议更改Ns。

void writeMTL(string filename)
{ofstream OutFile(filename); //利用构造函数创建obj文本char c1[300] = "# Blender 3.4.1 MTL File : 'None'\n# www.blender.org \n\nnewmtl mtl8\nNs 500.000000\nKa 1.000000 1.000000 1.000000\nKd 0.000000 0.000000 0.000000\nKs 0.500000 0.500000 0.500000\nKe 0.500000 0.500000 0.500000\nNi 1.000000\nd 1.000000\nillum 2\nmap_Kd 20";string c2 = "_1.png\n";for (int i = 0; c1[i] != 0; i++)//对字符逐个处理,直到遇到'/0'为止    {OutFile.put(c1[i]);}OutFile <<(num+c2).c_str()<<endl;OutFile.close();            //关闭文件
}

C++写纹理贴图中OBJ文件和MTL(材质)文件相关推荐

  1. solidworks导出obj模型和mtl材质

    目录 0.使用STL格式中转 1.使用solidworks宏 2.使用opencascade软件+step格式中转 为何会有这种需求?因为大多数3D库,都支持导入obj模型和mtl材质,例如webGL ...

  2. linux 利用cat写文件名,在LINUX中如何用cat创建一个文件

    满意答案 怪盗丶末三 2013.09.06 采纳率:43%    等级:12 已帮助:12722人 cat 的创建.连接文件功能实例,如下 cat 有创建文件的功能,创建文件后,要以EOF或STOP结 ...

  3. three.js obj模型的mtl材质贴图不显示

    在加载成功后模型会显示黑色或者白色模块,但是mtl文件是加载成功的,如果在mtl中使用了纹理贴图,需要在mtl文件中修改一下纹理贴图的路径(不只是需要mtl文件,还需要贴图文件),这里的路径是图片的相 ...

  4. obj文件格式与.mtl文件格式

    1.OBJ是一种3D模型文件,因此不包含动画.材质特性.贴图路径.动力学.粒子等信息.但是可以读取.mtl文件来获得材质信息. 2.OBJ文件使用[关键字根据数据类型排列,每个关键字有一段简短描述] ...

  5. 计算机图形学与opengl C++版 学习笔记 第5章 纹理贴图

    目录 5.1 加载纹理图像文件 5.2 纹理坐标 5.3 创建纹理对象 5.4 构建纹理坐标 5.5 将纹理坐标载入缓冲区 5.6 在着色器中使用纹理:采样器变量和纹理单元 5.7 纹理贴图:示例程序 ...

  6. openGL法线贴图和纹理贴图结合使用,以增强三维物体表面细节

    openGL系列文章目录 文章目录 openGL系列文章目录 前言 一.法线贴图? 二.代码 1.主程序 2.着色器程序 运行效果 源码下载 前言 凹凸贴图的一种替代方法是使用查找表来替换法向量.这样 ...

  7. dx12 龙书第九章学习笔记 -- 纹理贴图

    1.纹理与资源的回顾 我们其实很早就接触过纹理了,之前的深度缓冲区与后台缓冲区,它们都是通过ID3D12Resource接口表示,并以D3D12_RESOURCE_DESC::Dimension成员中 ...

  8. VTK笔记-纹理贴图-vtkTexture类

    纹理贴图   计算机图形学中的纹理既包括通常意义上物体表面的纹理即使物体表面呈现凹凸不平的沟纹,同时也包括在物体的光滑表面上的彩色图案,通常我们更多地称之为花纹.对于花纹而言,就是在物体表面绘出彩色花 ...

  9. OpenGL着色器程序解析--纹理贴图

    背景 纹理贴图意思是将任意类型的图片贴在3d模型的一个或者多个面上.图片可以是任意的但通常是一种通用的样式,比如:砖块.植物.荒芜的土地等等,可以提高场景的真实性.比较下面两幅图片:  为了实现纹理贴 ...

最新文章

  1. 分布式锁之三:Redlock实现分布式锁
  2. 307. Range Sum Query - Mutable | 307. 区域和检索 - 数组可修改(数据结构:线段树,图文详解)
  3. javascript --- 文件上传即时预览 闭包实现多图片即时预览
  4. 机器学习的练功心法(三)——特征工程
  5. Activiti配置实例以及Spring集成配置
  6. linux设置默认终端模拟器,ubuntu终端默认设置_在Ubuntu Linux上设置默认终端模拟器...
  7. socket编程---SCTP
  8. 怎样当一个企业舍不得的人
  9. MPP模块及sample_venc分析
  10. 利用ABBYY Screenshot Reader快速截取网页并识别文本
  11. css中自适应字体问题等
  12. 蜜罐合约-老版本solidity引用类型的一个坑
  13. 2020考研数学一大纲之完全解析(四)
  14. 10个成语理解项目管理的价值观和方法论
  15. 2020年408真题_2020年港澳台联考真题——地理!
  16. Shell中的括号、方括号、花括号、双括号和双方括号使用场景总结
  17. 习题5.4 找出4*5矩阵中值最小和最大元素,并分别输出其值及所在的行号和列号。
  18. 基于登录注册用ajax实现手机验证码功能
  19. 经典影视剧《大宋提刑官》——老剧重看,再添心得
  20. 霍营到北土城时间记录

热门文章

  1. Power Pivot随笔-DAX函数用法
  2. 智能手机应用的4个必备功能
  3. mysql为什么不使用存储过程_题外话,为什么不用数据库的存储过程
  4. [连载]Java程序设计(01)---任务驱动方式:英制单位转换成公制单位
  5. access-group和access-class的区别几用法
  6. 博士论文——基于卷积神经网络的人脸识别研究 __张燕红
  7. 光纤之父高锟:从痴人说梦到诺贝尔物理学奖
  8. 超简单且免费体验的手机短信验证,三分钟学会(包含c语言、c++、python、java、php等语言)
  9. 中国氟化稀土产业调研与投资战略报告(2022版)
  10. 结婚有风险,离婚须谨慎!