接上篇Unity导入STL格式模型(一),分成多个子网格的方式解决了导入慢以及目标模型顶点过多的问题,优化之后,目前针对二进制STL文件有比较良好的解析能力。

MeshCompression:是否使用压缩模式

Off为不使用,跳过压缩算法,导入模型的时间可以短到忽略不计。

On为使用,会为每个子网格单独压缩,也就是删掉所有他认为重复的顶点(位置相等他就认为重复)。

SingleTrianglesNumber:以此数量做为子网格的面数进行拆分,将模型分为多个子网格。

SaveMesh:是否保存模型的所有子网格至本地磁盘?在CreateInstance至Scene中之后。

核心代码如下:

///

/// 创建STL模型实例

///

private void CreateInstance()

if (_singleTrianglesNumber < 1000 || _singleTrianglesNumber > 20000)

Debug.LogError("Single Triangles Number: this value is unreasonable!");

return;

if (int.Parse(_trianglescount) > 200000)

Debug.LogError("Triangles Count: this value is too much!");

return;

string fullPath = Path.GetFullPath(AssetDatabase.GetAssetPath(target));

_total = int.Parse(_trianglescount);

_number = 0;

_binaryReader = new BinaryReader(File.Open(fullPath, FileMode.Open));

//抛弃前84个字节

_binaryReader.ReadBytes(84);

_vertices = new List();

_normals = new List();

_triangles = new List();

//读取顶点信息

Thread t = new Thread(ReadVertex);

t.Start();

while (_number < _total)

EditorUtility.DisplayProgressBar("读取信息", "正在读取顶点信息(" + _number + "/" + _total + ")......", (float)_number / _total);

CreateGameObject();

_binaryReader.Close();

EditorUtility.ClearProgressBar();

///

/// 读取顶点信息

///

private void ReadVertex()

while (_number < _total)

byte[] bytes;

bytes = _binaryReader.ReadBytes(50);

if (bytes.Length < 50)

_number += 1;

continue;

Vector3 vec0 = new Vector3(BitConverter.ToSingle(bytes, 0), BitConverter.ToSingle(bytes, 4), BitConverter.ToSingle(bytes, 8));

Vector3 vec1 = new Vector3(BitConverter.ToSingle(bytes, 12), BitConverter.ToSingle(bytes, 16), BitConverter.ToSingle(bytes, 20));

Vector3 vec2 = new Vector3(BitConverter.ToSingle(bytes, 24), BitConverter.ToSingle(bytes, 28), BitConverter.ToSingle(bytes, 32));

Vector3 vec3 = new Vector3(BitConverter.ToSingle(bytes, 36), BitConverter.ToSingle(bytes, 40), BitConverter.ToSingle(bytes, 44));

_normals.AddNormal(vec0);

_triangles.AddTriangle(_vertices.AddGetIndex(vec1), _vertices.AddGetIndex(vec2), _vertices.AddGetIndex(vec3));

_number += 1;

///

/// 创建GameObject

///

private void CreateGameObject()

string path = AssetDatabase.GetAssetPath(target);

string fullPath = Path.GetFullPath(path);

string assetPath = path.Substring(0, path.LastIndexOf("/")) + "/";

GameObject root = new GameObject(Path.GetFileNameWithoutExtension(fullPath));

root.transform.localPosition = Vector3.zero;

root.transform.localScale = Vector3.one;

int count = _total / _singleTrianglesNumber;

count += (_total % _singleTrianglesNumber > 0) ? 1 : 0;

for (int i = 0; i < count; i++)

GameObject tem = new GameObject(Path.GetFileNameWithoutExtension(fullPath) + "Sub" + i);

tem.transform.SetParent(root.transform);

tem.transform.localPosition = Vector3.zero;

tem.transform.localScale = Vector3.one;

MeshFilter mf = tem.AddComponent();

MeshRenderer mr = tem.AddComponent();

int startIndex = i * _singleTrianglesNumber * 3;

int length = _singleTrianglesNumber * 3;

if ((startIndex + length) > _vertices.Count)

length = _vertices.Count - startIndex;

List vertices = _vertices.GetRange(startIndex, length);

List normals = _normals.GetRange(startIndex, length);

List triangles = _triangles.GetRange(0, length);

//压缩网格

if (_meshCompression.IsOn())

MeshCompression(tem.name, vertices, normals, triangles);

Mesh m = new Mesh();

m.name = tem.name;

m.vertices = vertices.ToArray();

m.normals = normals.ToArray();

m.triangles = triangles.ToArray();

m.RecalculateNormals();

mf.mesh = m;

mr.material = new Material(Shader.Find("Standard"));

Debug.Log("Create done! " + tem.name + ": Vertex Number " + m.vertices.Length);

///

/// 压缩网格

///

/// 网格名称

/// 需要压缩的网格顶点数组

/// 与之对应的法线数组

/// 与之对应的三角面数组

private void MeshCompression(string meshName, List vertices, List normals, List triangles)

//移位补偿,当顶点被标记为待删除顶点时

int offset = 0;

//需要删除的顶点索引集合

List removes = new List();

for (int i = 0; i < vertices.Count; i++)

EditorUtility.DisplayProgressBar("压缩网格", "正在压缩网格[ " + meshName + " ](" + i + "/" + vertices.Count + ")......", (float)i / vertices.Count);

if (removes.Contains(i))

offset += 1;

continue;

triangles[i] = i - offset;

for (int j = i + 1; j < vertices.Count; j++)

if (vertices[i] == vertices[j])

removes.Add(j);

triangles[j] = triangles[i];

removes.Sort();

removes.Reverse();

for (int i = 0; i < removes.Count; i++)

vertices.RemoveAt(removes[i]);

normals.RemoveAt(removes[i]);

测试:使用不压缩网格模式,点击CreateInstance,导入的时间快到可以忽略不计,而且目标已被拆分为多个网格,再多顶点的模型也不用担心超过上限:

没有经过压缩的顶点数量分别为:

测试:然后我们使用压缩网格模式,点击CreateInstance,注意,这里勾选SaveMesh,以便于将网格保存在本地,便可重复使用,毕竟压缩模式导入比较慢,不用每次使用都重新压缩网格:

压缩之后的结果:

可以看到顶点几乎被压缩掉了四分之三,如果要考虑性能的话,还是使用压缩网格比较好,而且因为他替换掉的都是位置重复顶点,这些在视觉上是看不出任何差异的(没有贴图的话),而且我们保存在本地的Mesh文件之后便可以直接通过拖拽给MeshFilter组件使用,方便了很多。

github源码链接:https://github.com/SaiTingHu/ImportSTL

来自:http://blog.csdn.net/qq992817263/article/details/72738344

stl文件unity_Unity导入STL格式模型(二)相关推荐

  1. stl文件unity_Unity导入STL格式模型(一)

    STL文件是一种非常简单且实用的三角形网格文件,他只按照三角面片的方式存储了所有的面信息及法矢量,不包含纹理以及其他任何媒体信息,主要存储格式分为:ASCII码格式.二进制格式. 这种文件格式在工业上 ...

  2. python 读取stl文件_读取STL模型 并用opengl显示

    说起STL模型,相信使用过CAD三维软件的人都不陌生, STL = STL文件,一种3D模型文件格式STL(STereo Lithography的缩写) STL文件格式是由3D SYSTEMS 公司于 ...

  3. unity如何支持stl文件的导入

    stl文件为扫描生成的3d物体文件.stl原生是不支持stl导入的. 支持的方法也很简单: 打开Packages/manifest.json 将"co.parabox.stl":& ...

  4. Three导入dae格式模型实例

    DAE 是纯文本的模型格式,其本质就是一个单纯的xml文件.相比fbx,对dae格式模型的载入我们拥有非常高的自由控制,这也是最复杂的地方.基本上,dae文件内一开始就把数据分成了好几大块.对我们来说 ...

  5. ANSYS APDL学习(3):ANSYS APDL 导入x_t格式模型并受力分析范例

    ANSYS APDL 导入x_t格式模型并受力分析范例 第一步:导入模型 第二步:设置单元类型 第三步:划分网格 第四步:材料属性 第五步:施加位移约束和力 第七步:计算 第八步:查看结果 附上 命令 ...

  6. 旋转狗头:Python如何读取STL文件,生成STL文件预览图(缩略图)之进化,动态旋转Gif图

    之前的文章<Python如何读取STL文件,生成STL文件预览图(缩略图)>实现了将STL文件读取加载.绘制保存为某个角度下2D的png图片,作为预览图(缩略图).但是3D转2D,预览就丢 ...

  7. matlab读入stl文件,matlab读取stl文件

    设定 Facet Surface Smoothing (三角面片平滑)为 150 -> File (文件) -> Export (输出) -> 选择 .STL Mechanical ...

  8. Python如何读取STL文件,生成STL文件预览图(缩略图)

    如果你的项目也遇到了需要在后台将STL文件自动处理并生成预览图(缩略图)的需求,那么看本文就可以实现.如下图,我有一个狗头. 后台处理后生成的效果1: 后台处理后生成的效果2: 后台处理后生成的效果3 ...

  9. PostGIS FME导入fbx格式模型

    使用FME导入模型数据到PostGIS FME支持模型格式:fbx.obj.dae.stl.3ds(目前仅打通fbx) 环境: Win10 FME2020 Fbx格式数据 操作说明: 1.打开FME ...

  10. stl文件转stp (二次开发)

    前几天有个美女问我stl文件怎么处理,很尴尬我也处理不了,为了避免再次发生这种情况,所以我做了这个小软件.其下载链接将在文末给出.源码我已经上传GitHub,需要的可自取:https://github ...

最新文章

  1. tcp转串口_PROFIBUS DP与Modbus/TCP网络转换操作指南
  2. php.ini网站空白,php配置问题:拷贝php.ini后,测试页面无法显示(显示空白)
  3. Java面试基础篇——第九篇:BIO,NIO,AIO的区别
  4. 快速打开计算机磁盘的软件,提升电脑运行效率, 你需要快速整理磁盘碎片的工具...
  5. Grpc Proto To Nuget Package 插件使用说明
  6. C#LeetCode刷题之#530-二叉搜索树的最小绝对差(Minimum Absolute Difference in BST)
  7. Python可视化:Seaborn(三)
  8. java计算器算法描述_基于Java的计算器算法(源代码)
  9. 职教云怎么合并账号_云课堂智慧职教怎么注销账号
  10. “零基础圆梦华为RS HCNP”视频课程规划
  11. Java 大地坐标转经纬度,经纬度与WGS84坐标转换
  12. JavaScript 索引、关联、对象数组增删改查循环
  13. 技术经理、架构师、技术总监、VP、CTO,这些岗位都是如何挣出来
  14. 修改db_create_file_dest
  15. 本地设置测试域名转向
  16. F. Fitness Baker
  17. 构建WindowsPhone生态:梁念坚博士答记者问windowsphone
  18. 使用python爬取百度今日热点事件排行榜
  19. Vue项目设置ico
  20. windows 自带计算器介绍

热门文章

  1. 你们要的网络电话软件测评来了
  2. windows功能_支持 AirPlay/DLNA 功能的 Windows 影音播放软件 5KPlayer
  3. 复制文字到剪贴板的几种方法
  4. 2015061906 - firebug安装和下载(2)
  5. 重装系统后电脑只剩下C盘怎么办?怎样给电脑磁盘分区增加盘符?
  6. 计算机英语辅助翻译软件,计算机辅助翻译(CAT)软件 计算机辅助翻译(CAT)软件 v6.3.0.616...
  7. 你在家看电视,家里的电视也在看你?
  8. linux解压win10iso,ISO文件的解压和WINISO問題
  9. 【STM32训练—SIM900A模块】第二篇、STM32驱动SIM900A发送中文和英文短信
  10. GDI函数 StretchDIBits,StretchBlt 缩小图片会有黑点的问题解决办法