STL文件格式包括二进制文件(BINARY)和文本文件(ASCII)两种.
前面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;
}