*#利用matlab读取stl文件后,将其中三角形片数据×2后,保存到另一个stl文件,利用3D软件打开观察图形是否变为两倍。那么应该怎么做呢?
首先了解一下stl文件
STL(Stereo lithographic)文件格式是美国3D SYSTEMS公司提出的三维实体造型系统的一个接口标准,其接口格式规范。采用三角形面片离散地近似表示三维模型,目前已被工业界认为是快速成形(rapid prototypi ng)领域的标准描述文件格式。在逆向工程、有限元分析、医学成像系统、文物保护等方面有广泛的应用。
STL文件的最大特点也是其主要问题是,它是由一系列的三角形面片无序排列组合在一起的,没有反映三角形面片之间的拓扑关系。
stl文件分为二进制文件和ASCII文件两种:
二进制STL文件用固定的字节数来给出三角面片的几何信息。文件起始的80个字节是文件头,用于存贮零件名;紧接着用4个字节的整数来描述模型的三角面片个数,后面逐个给出每个三角面片的几何信息。每个三角面片占用固定的50个字节,依次是3个4字节浮点数(角面片的法矢量),3个4字节浮点数(1个顶点的坐标),3个4字节浮点数(2个顶点的坐标),3个4字节浮点数(3个顶点的坐标),最后2个字节用来描述三角面片的属性信息。一个完整二进制STL文件的大小为三角形面片数乘以50再加上84个字节,总共1 34个字节。
ASCII码格式的STL文件逐行给出三角面片的几何信息,每一行以1个或2个关键字开头。在STL文件中的三角面片的信息单元facet是一个带矢量方向的三角面片,STL三维模型就是由一系列这样的三角面片构成。整个STL文件的首行给出了文件路径及文件名。在一个STL文件中,每一个facet由7行数据组成,facetnormal是三角面片指向实体外部的法矢量坐标,outer loop说明随后的3行数据分别是三角面片的3个顶点坐标,3顶点沿指向实体外部的法矢量方向逆时针排列。
话不多说,直接上代码
读取ASCII文件:
clc;
t=cputime;
filefrom='城堡-ASCLL.stl';
fid1=fopen(filefrom);
fgetl(fid1);
data=fscanf(fid1,' facet normal %e %e %e\n outer loop\n vertex %e %e %e vertex %e %e %e vertex %e %e %e\n endloop\n endfacet\n');
fileto='城堡-ASCLL2.stl';
[length, w] = size(data);
fid2 = fopen(fileto, 'w');
data = data.*2;
fprintf(fid2, "solid 城堡-ASCLL2\n");
for i=1:length / 12
fprintf(fid2, ' facet normal %e %e %e\n outer loop\n vertex %e %e %e\n vertex %e %e %e\n vertex %e %e %e\n endloop\n endfacet\n', ...
data((i - 1) * 12 + 1:i* 12, 1) );
end
fprintf(fid2, "endsolid\n");
fclose(fid1);
fclose(fid2);
e=cputime-t;
disp('耗时为:');
disp(e);
读取二进制stl文件:
clear;
clc;
starttime = tic;
% 读取和写入的文件名
filenamefrom='城堡-二进制.stl';
filenameto = '城堡-二进制2.stl';
% 以二进制打开文件读取原文件
fid1 = fopen(filenamefrom, 'rb');
fid2 = fopen(filenameto, 'wb');
% 读出表头写入文件
data = fread(fid1, 80, 'uint8');
fwrite(fid2, data, 'uint8');
% 读出三角矩阵的个数
num = fread(fid1, 1, 'uint32');
fwrite(fid2, num, 'uint32');
% 将个数值翻倍之后,写入num个三角矩阵
for i=1:num
vector = fread(fid1, 12, 'float');
vector = vector.*2;
fwrite(fid2, vector, 'float');
attribute = fread(fid1, 1, 'uint16');
fwrite(fid2, attribute, 'uint16');
end
% 关文件
fclose(fid1);
fclose(fid2);
% 结束计时
timeelapsed = toc(starttime);
disp("运行时间:");
disp([num2str(timeelapsed),'s']);