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

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文件。如下图,利用文本编辑器将一个四面体的几何数据保存到文件中。



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



以上一个例子是手动创建一个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文件用固定的字节数来给出三角面片的几何信息。 
文件起始的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三维绘图软件打开效果如下:

猜你喜欢

转载自blog.csdn.net/qq_28249373/article/details/75305141