C++读取STL文件

ASCII码形式读取

STL文件格式如下,按照这个使用流读取即可

solid
 facet normal -1 0 0
  outer loop
   vertex -5.0999999046325684 -5.0999999046325684 39.900001525878906
   vertex -5.0999999046325684 -5.0999999046325684 49.818454742431641
   vertex -5.0999999046325684 -5.0701136589050293 49.815811157226562
  endloop
 endfacet

// solid: 放在文件开头,表示固体
// facet normal: 三角面片的法向量
// vertex: 三角面片的三个顶点

代码如下, 这里是将法向量和顶点按照1+3的形式一起读入了vector中

#include <vector>
#include <cstdio>
#include <string>
#include <fstream>

struct Point
{
	double x, y, z;
	Point() : x(0.0), y(0.0), z(0.0) {}
    Point(double x_, double y_) : x(x_), y(y_), z(0.0){}
	Point(double x_, double y_, double z_) : x(x_), y(y_), z(z_){}
	Point(const Point& p) : x(p.x), y(p.y), z(p.z){}

	Point& operator=(const Point& p)
	{
		x = p.x;
		y = p.y;
        z = p.z;
		return *this;
	}
	
};

void readAsciiSTL(const std::string& filepath, std::vector<Point>& points, bool is_print)
{
    if (is_print) printf("Reading binary file \" %s \"...\n", filepath.c_str());
    std::ifstream input(filepath);
    if (!input.is_open())
    {
        printf("\nError: %s, %d.\n", __FILE__, __LINE__);
        printf("Can not open file:\"%s\" .\n", filepath.c_str());
        exit(EXIT_FAILURE);
    }
    std::string s;
    while (input >> s)
    {
        if (s == "vertex" || s == "normal")
        {
            double x, y, z;
            input >> x >> y >> z;
            points.push_back(Point(x, y, z));
        }
    }
}

二进制形式读取

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

文件起始的80个字节是文件头,用于存贮文件名;

紧接着用 4 个字节的整数来描述模型的三角面片个数,

后面逐个给出每个三角面片的几何信息。每个三角面片占用固定的50个字节,依次是:

3个4字节浮点数(角面片的法矢量)

3个4字节浮点数(1个顶点的坐标)

3个4字节浮点数(2个顶点的坐标)

3个4字节浮点数(3个顶点的坐标)个

三角面片的最后2个字节用来描述三角面片的属性信息。

一个完整二进制STL文件的大小为三角形面片数乘以 50再加上84个字节。

依照格式,读取函数如下

#include <string>
#include <vector>
#include <fstream>
#include <cstdio>

struct Point
{
	double x, y, z;
	Point() : x(0.0), y(0.0), z(0.0) {}
    Point(double x_, double y_) : x(x_), y(y_), z(0.0){}
	Point(double x_, double y_, double z_) : x(x_), y(y_), z(z_){}
	Point(const Point& p) : x(p.x), y(p.y), z(p.z){}

	Point& operator=(const Point& p)
	{
		x = p.x;
		y = p.y;
        z = p.z;
		return *this;
	}
	
};

void readBinarySTL(const std::string& filepath, std::vector<Point>& points, bool is_print)
{
    if (is_print) printf("Reading %s...\n", filepath.c_str());
    std::ifstream input(filepath, std::ios::binary);
    if (!input.is_open())
    {
        printf("\nError: %s, %d\n",  __FILE__, __LINE__);
        printf("Cannot open file: %s\n", filepath.c_str());
        exit(EXIT_FAILURE);
    }

    // 跳过开头80个二进制码
    input.seekg(80);

    // 读取三角面片数量 4 字节
    uint32_t numTriangles;
    input.read(reinterpret_cast<char*>(&numTriangles), sizeof(numTriangles));

    // 读取每个三角面片
    for (uint32_t i = 0; i < numTriangles; ++i)
    {
        // 读取法向量 12 字节 
        float nx, ny, nz;
        input.read(reinterpret_cast<char*>(&nx), sizeof(nx));
        input.read(reinterpret_cast<char*>(&ny), sizeof(ny));
        input.read(reinterpret_cast<char*>(&nz), sizeof(nz));
        points.push_back(Point(nx, ny, nz));  // 存入法向量

        // 读取顶点 36 字节
        for (int j = 0; j < 3; ++j)
        {
            float x, y, z;
            input.read(reinterpret_cast<char*>(&x), sizeof(x));
            input.read(reinterpret_cast<char*>(&y), sizeof(y));
            input.read(reinterpret_cast<char*>(&z), sizeof(z));
            points.push_back(Point(x, y, z)); 
        }

        // 跳过属性 2 字节
        input.seekg(2, std::ios_base::cur);
    }
    input.close();
    
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值