笔者前两天帮师兄干了个活,从stl文件里提取金属板亚表面腐蚀缺陷的深度信息,以矩阵的形式给他。
模型如图所示
亚表面(即背部)由于腐蚀缺陷出现凹坑,要提取其深度信息。千辛万苦终于弄明白,特此在这里记录一下。
软件工具:matlab
matlab自2018b之后自带了stlread的函数,官方文档https://ww2.mathworks.cn/help/matlab/ref/stlread.html
官方文档基本说的很详细了TR = stlread(filename ) 返回 triangulation 对象TR,其中包含 STL 文件中的三角剖分数据
triangulation的官方文档https://ww2.mathworks.cn/help/matlab/ref/triangulation.html
这里用到 triangulation类的内置函数Points,获取对象TR中三角剖分的顶点坐标数据,matlab语句为
XYZ=TR.Points;
由于顶点数据是无序的,需要筛选出位于亚表面的顶点以计算缺陷深度。完整程序如下:
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%优化了扫查速度
clear;
tic;
[TR,fileformat,attributes,solidID] = stlread('18.stl');
XYZ=TR.Points;%板的法向沿y方向
%步长,受stl精细度限制
step=0.4;
%初始点
xstart=min(XYZ(:,1));
zstart=min(XYZ(:,3));
%矩阵大小,向下取整
xnums=floor((max(XYZ(:,1))-min(XYZ(:,1)))/step);
znums=floor((max(XYZ(:,3))-min(XYZ(:,3)))/step);
%坐标序列
xseries=xstart:step:max(XYZ(:,1));
zseries=zstart:step:max(XYZ(:,3));
%初始化矩阵
Depth=zeros(xnums,znums);
%以扫查步长内的最小y坐标作为作为该点的亚表面y坐标
hh = waitbar(0,'Searching...');
counter=0;
xflag=1;
xsort=sortrows(XYZ,1);
for cntx=1:xnums
xend=find(xsort(xflag:end,1)>xseries(cntx+1),1)+xflag-2;
zflag=1;
zsort=sortrows(xsort(xflag:xend,:),3);
for cntz=1:znums
zend=find(zsort(zflag:end,3)>zseries(cntz+1),1)+zflag-2;
Depth(cntx,cntz)=min(zsort(zflag:zend,2));
zflag=zend+1;
counter=1+counter;
waitbar(counter/(xnums)/(znums))
end
xflag=xend+1;
end
close(hh);
toc;
%深度
Depth(:,:)=Depth(:,:)-min(min(Depth));
%作图
zseries=zseries(1:end-1);
xseries=xseries(1:end-1);
surfc(zseries,xseries,Depth)
shading interp
alpha 0.8
xlabel('X (mm) ')
ylabel('Y (mm) ')
zlabel('Depth (mm)')
title('亚表面缺陷深度分布')
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
其中“18.stl”是位于程序同目录下的stl文件。
大概就这么多吧,欢迎大家参考~
|
请发表评论