MATLAB快速读取STL文件
HPC_ZY
利用MATLAB快速读取并解析STL文件。最近需要处理大型STL文件,使用MATLAB三方stlread仅是读取解析就花费大量时间。故自行学习并充分利用MATLAB的机制修改了STL解析方式,速度大大提升,在这里记录分享。
一、STL文件格式
binary格式
ascii格式stl
由于目前没拿到过这种格式的stl,所以暂时不讲
二、开源代码
安装方法
老样子,在附加功能中搜索“Computation of craniofacial symmetry”,看到一个蓝白骷髅头,就是它了。
使用方法
% 读取
[v,f,n] = stlRead('newdata.stl');
% 显示
patch('vertices',v,'faces',f,'edgecolor','none',...
'facecolor',[1 0 0],'facelighting','phong')
light
axis equal off
% 保存
stlWrite('newdata.stl',f,v);
查看源码可以发现,stlRead()
采用的是边读取边解析的方式,MATLAB处理for循环效率不高。
三、快速读取
由于MATLAB擅长处理矩阵运算,所以我们采取“先读取,再解析”的方法。
binary格式stl
%% 一、以二进制按字节读取数据
fp = fopen(fileName,'rb');
src = fread(fp,'uint8=>uint8');
fclose(fp);
%% 二、提取有效信息
% 提取数据长度信息(四字节无符号整形)
len = typecast(src(81:84),'uint32');
% 提取三角片信息([48有效字节+2填充字节]*len)
data = reshape(src(85:end),[50,len]);
data(end-1:end,:) = [];
% 类型转换(float*12*len)
dataf = typecast(data(:),'single');
dataf = reshape(dataf,[12,len]);
%% 三、获取v、f、n
% 获取v,f,n(注意MATLAB是列优先的,所以必须按下列方式写)
n = dataf(1:3,:)';
v = reshape(dataf(4:end,:),[3,len*3])';
f = reshape((1:len*3)',[3,len])';
% 去除重复顶点
[v, ~, indexn] = unique(v, 'rows');
f = indexn(f);
注:比如两个相邻三角片就有重复的定点,而多数原始STL数据并没有去除这些重复定点(这也是导致某些STL数据过大的原因之一)
ascii格式stl
由于目前没拿到过这种格式的stl,所以暂时不讲
四、效果对比
fileName = 'test.stl';
tic
% MATLAB三方
[v,f,n] = stlRead(fileName);
toc
tic
% 个人
[v,f,n] = stlfastread(fileName);
toc
因为充分利用的MATLAB对矩阵的处理,提速很明显。
其他
欢迎小伙伴提供 ascii格式的stl
2023年3月21日补充:过去几年了,已经不研究STL了。ASCII格式的小伙伴可以直接使用MATLAB提供的函数读,如果觉得太慢了不能接受,可以尝试看源码自己优化。嘿嘿