数据格式
二进制的数据格式:
二进制STL文件用固定的字节数来给出三角面片的几何信息。
- 【80】80个字节的文件头,用于存贮文件名
- 【4】 4 个字节的int描述模型的三角面片个数(小端存储)
- 【50*n】一个三角面片占用固定的50个字节(小端存储),依次是:
- 【12】3个4字节浮点数(角面片的法矢量)
- 【12】3个4字节浮点数(1个顶点的坐标)
- 【12】3个4字节浮点数(2个顶点的坐标)
- 【12】3个4字节浮点数(3个顶点的坐标)个
- 【2】三角面片的最后2个字节用来描述三角面片的属性信息。
一个完整二进制STL文件的大小为三角形面片数乘以 50再加上84个字节。
ASCII的数据格式
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
例子
此处将完整展示将一个二进制格式STL文件导入到程序中的过程。
利用solidworks建立了一个10X10mm²的方形面片,并将其导出为二进制STL
利用notepad++的HEX-Editor插件查看二进制文件
选中的二进制段落就是第一个三角面的全部信息
STL中的浮点数格式符合IEEE制定的float格式,并且是小端存储,在x86系统中编译可以直接利用memcpy函数拷贝到C++的float中
在线浮点数转换
表1 三角面1
表项 | X | Y | Z | 坐标 |
---|
法向量 | 00000000 | 00000000 | 3f800000 | (0,0,1) |
点1 | 00000000 | 00000000 | 00000000 | (0,0,0) |
点2 | 41200000 | 00000000 | 00000000 | (10,0,0) |
点3 | 00000000 | 41200000 | 00000000 | (0,10,0) |
三角面标记 | 0000 | | | |
代码
这段代码的功能是识别一个STL文件是二进制或是ASCII格式,并将内部的三角面存储到vector容器中。
ReadSTLFile.cpp
#pragma once
#include <vector>
#include <fstream>
#include"Point3f.h"
#include <iostream>
#include <string>
#include"ReadSTLFile.h"
#include <sstream>
using namespace std;
bool ReadSTLFile::ReadFile(const char *cfilename)
{
FILE * pFile;
long lSize;
char* buffer;
size_t result;
fopen_s(&pFile,cfilename, "rb");
if (pFile == NULL)
{
fputs("File error", stderr);
exit(1);
}
fseek(pFile, 0, SEEK_END);
lSize = ftell(pFile);
rewind(pFile);
buffer = (char*)malloc(sizeof(char)*lSize);
if (buffer == NULL)
{
fputs("Memory error", stderr);
exit(2);
}
result = fread(buffer, 1, lSize, pFile);
if (result != lSize)
{
fputs("Reading error", stderr);
exit(3);
}
fclose(pFile);
ios::sync_with_stdio(false);
if (buffer[79]!='\0')
{
ReadASCII(buffer);
}
else
{
ReadBinary(buffer);
}
ios::sync_with_stdio(true);
free(buffer);
return true;
}
bool ReadSTLFile::ReadASCII(const char *buffer)
{
unTriangles = 0;
float x, y, z;
int i;
string name, useless;
stringstream ss(buffer);
ss >> name >> name;
ss.get();
do {
ss >> useless;
if (useless != "facet")
break;
getline(ss, useless);
getline(ss, useless);
for (i = 0; i < 3; i++)
{
ss >> useless >> x >> y >> z;
pointList.push_back(Point3f(x, y, z));
}
unTriangles++;
getline(ss, useless);
getline(ss, useless);
getline(ss, useless);
} while (1);
return true;
}
bool ReadSTLFile::ReadBinary(const char *buffer)
{
const char* p = buffer;
char name[80];
int i, j;
memcpy(name, p, 80);
p += 80;
unTriangles= cpyint(p);
for (i = 0; i < unTriangles; i++)
{
p += 12;
for (j = 0; j < 3; j++)
pointList.push_back(Point3f(cpyfloat(p), cpyfloat(p), cpyfloat(p)));
p += 2;
}
return true;
}
int ReadSTLFile::NumTri()
{
return unTriangles;
}
vector<Point3f>& ReadSTLFile::PointList()
{
return pointList;
}
int ReadSTLFile::cpyint(const char*& p)
{
int cpy;
memwriter = (char*)&cpy;
memcpy(memwriter, p, 4);
p += 4;
return cpy;
}
float ReadSTLFile::cpyfloat(const char*& p)
{
float cpy;
memwriter = (char*)&cpy;
memcpy(memwriter, p, 4);
p += 4;
return cpy;
}
ReadSTLFile.h
#pragma once
#include<vector>
#include"Point3f.h"
using namespace std;
class ReadSTLFile
{
public:
bool ReadFile(const char *cfilename);
int NumTri();
vector<Point3f>& PointList();
private:
vector<Point3f> pointList;
unsigned int unTriangles;
bool ReadASCII(const char *cfilename);
bool ReadBinary(const char *cfilename);
char* memwriter;
int cpyint(const char*& p);
float cpyfloat(const char*& p);
};
Point3f.cpp
#pragma once
#include"Point3f.h"
Point3f::Point3f():x(0),y(0),z(0)
{
}
Point3f::Point3f(float _x, float _y, float _z) :x(_x), y(_y), z(_z)
{
}
int Point3f::SetParam(float _x, float _y, float _z)
{
x = _x;
y = _y;
z = _z;
return 0;
}
Point3f.h
#pragma once
#include<d3d9.h>
#include<d3dx9math.h>
#include<windows.h>
struct Vertex
{
Vertex() {}
Vertex(float x, float y, float z)
{
_x = x; _y = y; _z = z;
}
float _x, _y, _z;
static const DWORD FVF;
};
class Point3f
{
public:
Point3f();
Point3f(float _x,float _y,float _z);
int SetParam(float _x, float _y, float _z);
inline Vertex IVertex()
{
return Vertex(x, y, z);
}
private:
float x, y, z;
};
效果
方形面片读取
上述内存为:
00000000 00000000 00000000
00000000 00000000 00002041
00000000 00002041 00000000
00000000 00002041 00000000
00000000 00000000 00002041
00000000 00002041 00002041
即方形面片的STL数据
稍微复杂的读取:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)