MATLAB快速讀取STL檔案

HPC_ZY發表於2020-11-30

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

相關文章