如何将顶点数据保存为STL文件?

时间:2022-07-06 11:51:04
stl 文件是在计算机图形应用系统中,用于表示三角形网格的一种文件格式。 它的文件格式非常简单, 应用很广泛。STL是最多快速模型系统所应用的标准文件类型。STL是用三角网格来表现3D CAD模型。
STL只能用来表示封闭的面或者体,stl文件有两种:一种是ASCII明码格式,另一种是二进制格式。注:文字描述部分,大部分应用了百度百科。
一、STL文件的格式
(1)ASCII明码格式
ASCII码格式的STL文件逐行给出三角面片的几何信息,每一行以1个或2个关键字开头。 在STL文件中的三角面片的信息单元 facet 是一个带矢量方向的三角面片,STL三维模型就是由一系列这样的三角面片构成。 整个STL文件的首行给出了文件路径及文件名。 在一个 STL文件中,每一个facet由7 行数据组成, facet normal 是三角面片指向实体外部的法矢量坐标, outer loop 说明随后的3行数据分别是三角面片的3个顶点坐标,3顶点沿指向实体外部的法矢量方向逆时针排列。ASCII格式的STL 文件结构如下:
//中括号里面的是要填充的内容
solid   [filename]    //文件名,可以是任何字符
facet   normal  [i j k]//面的法线,i、j、k为三个分量,各分量之间用空格隔开,不能用逗号隔开
outor   loop
vertex  [x y z]//三角面片的第一个点,x、y、z三个坐标之间要用空格隔开
vertex  [x y z]//三角面片的第二个点
vertex  [x y z]//三角面片的第三个点
endloop
endfacet//完成一个三角面片的定义
、、、、//其他facet
endsolid [filename]//完成一个stl文件的定义

示例:
在电脑上新建一个txt文件,然后编辑。编辑完了之后保存,并将文件后缀名改为stl,即可完成一个创建了一个stl文件。如下图,利用文本编辑器将一个四面体的几何数据保存到文件中。

如何将顶点数据保存为STL文件?

文件做好之后,使用window系统自带的Print 3D 或者View 3D软件进行打开测试,显示结果如下:

如何将顶点数据保存为STL文件?

以上一个例子是手动创建一个stl文件,用来保存总共四个顶点的四面体。如果有大量的数据,这样做肯定是不行的。为此,根据stl文件的定义,用C语言编写了生成
stl文件的代码。代码仍然是保存一个简单的四面体数据。代码如下:
#include<stdio.h>
#include<string.h>

char head[128];//文件头

//法线
struct Normal
{
float i;
float j;
float k;
};

//点
struct Point
{
float x;
float y;
float z;
};

//面
struct Face
{
Normal normal;
Point p1;
Point p2;
Point p3;
};

int main()
{
char partName[64];

printf("请输入部件的名称:\n");
gets_s(partName);

//下面三条代码生成一个文件头
strcpy(head, "solid ");
strcat(head, partName);

//四面体的四个面
Face face[4];

face[0].normal = { 0,1,0 };
face[0].p1 = { 0,0,0 };
face[0].p2 = { 0,0,-100 };
face[0].p3 = { 100,0,0 };

face[1].normal = { -1,0,0 };
face[1].p1 = { 0,0,0 };
face[1].p2 = { 0,100,0 };
face[1].p3 = { 0,0,-100 };

face[2].normal = { 0,0,1 };
face[2].p1 = { 0,0,0 };
face[2].p2 = { 100,0,0 };
face[2].p3 = { 0,100,0 };

face[3].normal = { 1,1,-1 };
face[3].p1 = { 0,100,0 };
face[3].p2 = { 100,0,0 };
face[3].p3 = { 0,0,-100 };

FILE *fp;

fp = fopen("part.stl", "w");

if (fp != NULL)
{
fprintf(fp, "%s\n", head);//先写入文件头

//循环写入法线、顶点等数据
for (int i = 0;i < 4;i++)
{
fprintf(fp, "%s %f %f %f\n", "facet normal", face[i].normal.i, face[i].normal.j, face[i].normal.k);
fprintf(fp, "%s\n", "outor loop");
fprintf(fp, "%s %f %f %f\n", "vertex ", face[i].p1.x, face[i].p1.y, face[i].p1.z);
fprintf(fp, "%s %f %f %f\n", "vertex ", face[i].p2.x, face[i].p2.y, face[i].p2.z);
fprintf(fp, "%s %f %f %f\n", "vertex ", face[i].p3.x, face[i].p3.y, face[i].p3.z);
fprintf(fp, "%s\n", "endloop");
fprintf(fp, "%s\n", "endfacet");
}

fprintf(fp, "%s %s\n", "endsolid", partName);//写入文件尾
printf("成功生成stl文件");

}

return 0;
}

该程序生成了一个名为part.stl的文件。用记事本打开可以看到里面的文本:
如何将顶点数据保存为STL文件?
二、STL的二进制格式
二进制STL文件用固定的字节数来给出三角面片的几何信息。 
文件起始的80个字节是文件头,用于存贮文件名; 
紧接着用 4 个字节的整数来描述模型的三角面片个数, 后面逐个给出每个三角面片的几何信息。每个三角面片占用固定的50个字节,依次是: 
3个4字节浮点数(角面片的法矢量) 
3个4字节浮点数(1个顶点的坐标) 
3个4字节浮点数(2个顶点的坐标) 
3个4字节浮点数(3个顶点的坐标)
 三角面片的最后2个字节用来描述三角面片的属性信息。 一个完整二进制STL文件的大小为三角形面片数乘以 50再加上84个字节。
 用C语言去定义二进制的STL文件如下:
char   fileName[80];//文件名,固定为80个字节,可以是任何字符
int      faceNum;//三角片面的数目,固定4个字节
float  normal[3];//法线,三个浮点型的数据,共12字节
float  vertex1[3];//顶点一,共12字节
float  vertex2[3];//顶点二,共12字节
float  vertex3[3];//顶点三,共12字节
char  reserve[2];//保留项,一般用不到,只是预留两字节的位置
、、、、、、、、、  //其他三角片面
一个stl文件至少具有一个三角片面,一个三角片面固定为50个字节,因此,一个stl文件至少具有84+50=134个字节。三角片面越多,文件越大。
下面是用C语言生成的二进制格式STL文件的例子:将一个四面体几何数据保存为二进制的stl。
#include<stdio.h>

//文件头,共84字节
struct Head
{
char fileName[80];//零件名称
int faceNum;//面的数目
};

//点,三个float类型的,大小为12字节
struct Point
{
float x;
float y;
float z;
};

//法线
struct Normal
{
float i;
float j;
float k;
};

//三角面,由一个法线,三个点,和一个两字节的保留项,一共50字节
struct Face
{
Normal normal;
Point p1;
Point p2;
Point p3;
char info[2];//保留数据,可以不用管
};

int main()
{
Head head;
printf("请输入零件名:");
gets_s(head.fileName);
head.faceNum = 4;//三角面的数目为四
Face face1,face2,face3,face4;//四个面

face1.normal = { 0,1,0 };
face1.p1 = { 0,0,0 };
face1.p2 = { 0,0,-100 };
face1.p3 = { 100,0,0 };

face2.normal = { -1,0,0 };
face2.p1 = { 0,0,0 };
face2.p2 = { 0,100,0 };
face2.p3 = { 0,0,-100 };

face3.normal = { 0,0,1 };
face3.p1 = { 0,0,0 };
face3.p2 = { 100,0,0 };
face3.p3 = { 0,100,0 };

face4.normal = { 1,1,-1 };
face4.p1 = { 0,100,0 };
face4.p2 = { 100,0,0 };
face4.p3 = { 0,0,-100 };

FILE *fp;
errno_t err;

err = fopen_s(&fp, "myStl.stl", "wb");

if (err == 0)
{
fwrite(&head,84, 1, fp);
fwrite(&face1, 50, 1, fp);
fwrite(&face2, 50, 1, fp);
fwrite(&face3, 50, 1, fp);
fwrite(&face4, 50, 1, fp);
printf("生成文件成功!");
fclose(fp);
}
else
{
printf("无法创建文件");
}
return 0;
}

生成的文件名为mySTL.stl,用SolidWorks三维绘图软件打开效果如下:
如何将顶点数据保存为STL文件?