.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, " "); while (a[i] != " ") { if (!islower((int)a[i]) && !isupper((int)a[i]) && a[i] != " ") break; cnt++; i++; } while (a[cnt] != " ") { str[j] = a[cnt]; cnt++; j++; } str[j] = " "; 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; }
- 上一篇: 关于NMAKE
- 下一篇: c++实现三维向量的操作