zoukankan      html  css  js  c++  java
  • 读取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     // 第三个顶点坐标
        endloop
    endfacet                       // 完成一个三角形的定义
    
    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 triangle
    REAL32[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, '
    ');
            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());
    
        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
  • 相关阅读:
    Superwebsocket 模拟微信聊天室
    python杂记-6(time&datetime模块)
    python杂记-5(装饰器)
    python杂记-4(迭代器&生成器)
    python杂记-3(购买商品)
    python杂记-2(python之文件)
    python杂记-1(os模块)
    淘宝链接中的spm参数
    分布式Web服务器架构(转)
    asp.net网站增加虚拟目录,用来访问网站图片。
  • 原文地址:https://www.cnblogs.com/clairvoyant/p/5879046.html
Copyright © 2011-2022 走看看