首页 > 代码库 > 读取STL文件模型

读取STL文件模型

STL是CAD软件中出来的一种3D模型文件格式,wiki已经解释的很清楚了。

STL文件两种格式,ASCII STLBinary STL

ASCII STL,每一个facet由7行数据组成,outer loop后面三个顶点的顺序沿法线矢量逆时针排序,格式如下:

solid name // 文件名及文件路径facet normal ni nj nk          // 三角形法向量的三个分量    outer loop        vertex v1x v1y v1z     // 第一个顶点坐标        vertex v2x v2y v2z     // 第二个顶点坐标        vertex v3x v3y v3z     // 第三个顶点坐标    endloopendfacet                       // 完成一个三角形的定义endsolid name                  // 整个文件结束

Binary STL,起始有80个字节文件头用于存储文件名,紧接4个字节表示三角形数量,而每个三角面片占用固定的50个字节,3个4字节浮点数(法线矢量),3个4字节浮点数(第一个顶点坐标),3个4字节浮点数(第二个顶点坐标),3个4字节浮点数(第三个顶点坐标),接着2个字节描述三角形基本属性,那么一个完整的二进制STL文件的字节大小就是三角形面数乘50再加上84字节,格式如下:

UINT8[80] – Header             // 文件头UINT32 – Number of triangles   // 三角形数量foreach triangleREAL32[3] – Normal vector      // 法线矢量REAL32[3] – Vertex 1           // 第一个顶点坐标REAL32[3] – Vertex 2           // 第二个顶点坐标REAL32[3] – Vertex 3           // 第三个顶点坐标UINT16 – Attribute byte count  // 文件属性end

下面为代码,

技术分享
#include <fstream>#include <string>#include <vector>bool ReadSTLFile(const char *cfilename){    if (cfilename == NULL)        return false;    std::ifstream in(cfilename, std::ifstream::in);    if (!in)        return false;    std::string headStr;    getline(in, headStr,  );    in.close();    if (headStr.empty())        return false;    if (headStr[0] == s)    {        ReadASCII(cfilename);    }    else    {        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;    std::ifstream in(cfilename, std::ifstream::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());    return true;}bool ReadBinary(const char *cfilename){    std::vector<float> coorX;    std::vector<float> coorY;    std::vector<float> coorZ;    char str[80];    std::ifstream in(cfilename, std::ifstream::in | std::ifstream::binary);    if (!in)        return false;    in.read(str, 80);    //number of triangles      int triangles;    in.read((char*)&triangles, sizeof(int));    if (triangles == 0)        return false;    for (int i = 0; i < triangles; 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();    return true;}
ReadSTLFile

 

读取STL文件模型