.stl文件(CAD三维模型)格式 及 基于C/C++的数据读取

STL文件格式包括二进制文件(BINARY)文本文件(ASCII)两种.


BINARY格式:
二进制STL文件用固定的字节数来给出三角面片的几何信息。

前面84个字节描述3D模型文件信息。文件起始的80个字节是文件头,用于存贮零件名;紧接着用 4个字节的整数来描述模型的三角面片个数。

后面逐个给出每个三角面片的几何信息.每个三角面片占用固定的50个字节,依次是 3个4 字节浮点数(角面片的法矢量)3个4 字节浮点数(第一个个顶点的坐标)3个4 字节浮点数(第二个顶点的坐标)3个4 字节浮点数(第三个顶点的坐标)最后2个字节用来描述三角面片的属性信息


ASCII格式:

ASCII码格式的STL文件逐行给出三角面片的几何信息,每一行以1个或2个关键字开头。在STL文件中的三角面片的信息单元 facet 是一个带矢量方向的三角面片,STL 三维模型就是由一系列这样的三角面片构成。整个STL文件首行给出了文件路径及文件名。在一个 STL 文件中,每一个 facet 由 7 行数据组成,facet normal是三角面片指向实体外部的法矢量坐标,outer loop说明随后的3行数据分别是三角面片的 3 个顶点坐标,3 顶点沿指向实体外部的法矢量方向逆时针排列。

solid filename stl   //自定义文件头 
   facet normal x y z  //三角面片法向量的3个
       outer loop 
           vertex x y z       //三角面片第一个顶点坐标 
           vertex x y z       //三角面片第二个顶点坐标 
           vertex x y z       //三角面片第三个顶点坐标 
      endloop   
   endfacet         //完成一个三角面片定义 
   …… 
endsolid filename stl ∥整个STL文件定义结束


读取代码:

bool ReadSTLFile(const char *cfilename)
{
	if (cfilename == NULL)
		return false;

	ifstream in(cfilename, ios::in);
	if (!in)
		return false;

	string headStr;
	getline(in, headStr, ' ');
	in.close();

	if (headStr.empty())
		return false;

	if (headStr[0] == 's')
	{
		cout << "ASCII File." << endl;
		ReadASCII(cfilename);
	}		
	else
	{
		cout << "Binary File." << endl;
		ReadBinary(cfilename);
	}
	return true;
}

bool ReadASCII(const char *cfilename)
{
	std::vector<float> coorX;
	std::vector<float> coorY;
	std::vector<float> coorZ;

	int i = 0, j = 0, cnt = 0, pCnt = 4;
	char a[100];
	char str[100];
	double x = 0, y = 0, z = 0;

	ifstream in;
	in.open(cfilename, ios::in);
	if (!in)
		return false;
	do
	{
		i = 0;
		cnt = 0;
		in.getline(a, 100, '\n');
		while (a[i] != '\0')
		{
			if (!islower((int)a[i]) && !isupper((int)a[i]) && a[i] != ' ')
				break;
			cnt++;
			i++;
		}

		while (a[cnt] != '\0')
		{
			str[j] = a[cnt];
			cnt++;
			j++;
		}
		str[j] = '\0';
		j = 0;

		if (sscanf(str, "%lf%lf%lf", &x, &y, &z) == 3)
		{
			coorX.push_back(x);
			coorY.push_back(y);
			coorZ.push_back(z);
		}
		pCnt++;
	} while (!in.eof());

	// 	cout << "******  ACSII FILES ******" << endl;
	// 	for (int i = 0; i < coorX.size();i++)
	// 	{
	// 		cout << coorX[i] << " : " << coorY[i] << " : " << coorZ[i] << endl;
	// 	}

	cout << coorX.size() / 3 << " triangles." << endl;
	return true;
}

bool ReadBinary(const char *cfilename)
{
	std::vector<float> coorX;
	std::vector<float> coorY;
	std::vector<float> coorZ;
	
	char str[80];
	ifstream in;
	
	in.open(cfilename, ios::in | ios::binary);

	if (!in)
		return false;

	in.read(str, 80);

	//number of triangles
	int unTriangles;
	in.read((char*)&unTriangles, sizeof(int));

	if (unTriangles == 0)
		return false;

	for (int i = 0; i < unTriangles; i++)
	{
		float coorXYZ[12];
		in.read((char*)coorXYZ, 12 * sizeof(float));

		for (int j = 1; j < 4; j++)
		{
			coorX.push_back(coorXYZ[j * 3]);
			coorY.push_back(coorXYZ[j * 3 + 1]);
			coorZ.push_back(coorXYZ[j * 3 + 2]);
		}

		in.read((char*)coorXYZ, 2);
	}

	in.close();

	cout << coorX.size() / 3 << " triangles." << endl;
	return true;
}


 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值