在wiki上有对STL图形文件格式的详细描述。
http://en.wikipedia.org/wiki/STL_(file_format)
STL文件格式分为两种:ASCII字符格式,及二进制格式。
ASCII字符格式的格式如下:
开头一行:
solid name // 文件名是可选的字符串
接下来,是三角片的数据格式:
facet normal ni nj nk
outer loop
vertex v1xv1yv1z
vertex v2xv2yv2z
vertex v3xv3yv3z
endloop
endfacet
结束行标志:
endsolid name
二进制格式数据:
因为字符格式的STL文件比较大,占空间,因为有了二进制格式,且二进制的存储格式与ASCII的格式不同。二进制有80个字节作为文件头,一般都忽略掉,但开头不能使solid,不然就不能与ASCII格式相区分了。 另外,接下来4个字节是存放的三角片的个数,这个是ASCII格式所没有 的。
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
读取STL文件,首先,程序要区别读取的是那种格式的STL。然后根据格式,来读取数据。
先定义如下数据类型:
template <int D, class T = float>
class Vec {
private:
T v[D];
public:
...
};
typedef Vec<3,float> Vec3f;
用于存放点坐标数据和法向量数据,这里将点坐标和法向量都读到一个数组中。
-
boolReadSTLFile(constchar*cfilename)
- {
-
if(cfilename==NULL)
- {
-
returnfalse;
- }
-
- ifstreamin(cfilename,ios::in);
-
if(!in)
- {
-
returnfalse;
- }
- stringheadStr;
- getline(in,headStr,'');
-
- in.close();
-
-
-
if(headStr.empty())
- {
-
returnfalse;
- }
-
-
if(headStr[0]=='s')
- {
- ReadASCII(cfilename);
- }
- else
- {
- ReadBinary(cfilename);
- }
-
-
returntrue;
- }
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')
{
ReadASCII(cfilename);
}
else
{
ReadBinary(cfilename);
}
return true;
}
-
boolReadASCII(constchar*cfilename)
- {
-
inti=0,j=0,cnt=0,pCnt=4;
-
chara[100];
-
charstr[100];
-
doublex=0,y=0,z=0;
- Vec3ftPoint;
- Vector<Vec3f>pointList;
-
- ifstreamin;
- in.open(cfilename,ios::in);
-
if(!in)
- {
-
returnfalse;
- }
- 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)
- {
- tPoint.SetParam(x,y,z);
- pointList.push_back(tPoint);
- }
- pCnt++;
- }while(!in.eof());
-
-
returntrue;
- }
-
-
boolReadBinary(constchar*cfilename)
- {
-
charstr[80];
-
- ifstreamin;
-
intunTriangles(0);
- in.open(cfilename,ios::in);
-
-
if(!in)
- {
-
returnfalse;
- }
-
- in.read(str,80);
-
- in>>unTriangles;
-
-
if(unTriangles==0)
- {
-
returnfalse;
- }
-
- Vec3ftPoint;
- vector<Vec3f>pointList(unTriangles);
-
floatx(0.f),y(0.f),z(0.f);
-
charunusedByte;
-
for(inti=0;i<(int)unTriangles;i++)
- {
-
for(intpointIdx=0;pointIdx<4;pointIdx++)
- {
- in>>x>>y>>z;
- tPoint.SetParam(x,y,z);
- pointList.push_back(tPoint);
- }
-
- in>>unusedByte>>unusedByte;
- }
-
- in.close();
-
-
returntrue;
- }
bool ReadASCII(const char *cfilename)
{
int i=0,j=0,cnt=0 ,pCnt=4;
char a[100];
char str[100];
double x=0,y=0,z=0;
Vec3f tPoint;
Vector<Vec3f> pointList; // todo: 可以预先计算出pointList的大小,节省空间
ifstream in;
in.open(cfilename, ios::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)
{
tPoint.SetParam(x,y,z);
pointList.push_back(tPoint);
}
pCnt++;
}while(!in.eof());
return true;
}
bool ReadBinary(const char *cfilename)
{
char str[80];
ifstream in;
//三角形数目
int unTriangles(0);
in.open(cfilename, ios::in);
if (!in)
{
return false;
}
in.read(str, 80);
in >> unTriangles;
if(unTriangles==0)
{
return false;
}
Vec3f tPoint;
vector<Vec3f> pointList(unTriangles); // 预留足够的空间
float x(0.f), y(0.f), z(0.f);
char unusedByte;
//Binary
for(int i=0;i<(int)unTriangles;i++)
{
for (int pointIdx=0; pointIdx<4; pointIdx++)
{
in >> x >> y >> z;
tPoint.SetParam(x, y, z);
pointList.push_back(tPoint);
}
in >> unusedByte >> unusedByte;
}
in.close();
return true;
}
在wiki上有对STL图形文件格式的详细描述。
http://en.wikipedia.org/wiki/STL_(file_format)
STL文件格式分为两种:ASCII字符格式,及二进制格式。
ASCII字符格式的格式如下:
开头一行:
solid name // 文件名是可选的字符串
接下来,是三角片的数据格式:
facet normal ni nj nk
outer loop
vertex v1xv1yv1z
vertex v2xv2yv2z
vertex v3xv3yv3z
endloop
endfacet
结束行标志:
endsolid name
二进制格式数据:
因为字符格式的STL文件比较大,占空间,因为有了二进制格式,且二进制的存储格式与ASCII的格式不同。二进制有80个字节作为文件头,一般都忽略掉,但开头不能使solid,不然就不能与ASCII格式相区分了。 另外,接下来4个字节是存放的三角片的个数,这个是ASCII格式所没有 的。
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
读取STL文件,首先,程序要区别读取的是那种格式的STL。然后根据格式,来读取数据。
先定义如下数据类型:
template <int D, class T = float>
class Vec {
private:
T v[D];
public:
...
};
typedef Vec<3,float> Vec3f;
用于存放点坐标数据和法向量数据,这里将点坐标和法向量都读到一个数组中。
-
boolReadSTLFile(constchar*cfilename)
- {
-
if(cfilename==NULL)
- {
-
returnfalse;
- }
-
- ifstreamin(cfilename,ios::in);
-
if(!in)
- {
-
returnfalse;
- }
- stringheadStr;
- getline(in,headStr,'');
-
- in.close();
-
-
-
if(headStr.empty())
- {
-
returnfalse;
- }
-
-
if(headStr[0]=='s')
- {
- ReadASCII(cfilename);
- }
- else
- {
- ReadBinary(cfilename);
- }
-
-
returntrue;
- }
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')
{
ReadASCII(cfilename);
}
else
{
ReadBinary(cfilename);
}
return true;
}
-
boolReadASCII(constchar*cfilename)
- {
-
inti=0,j=0,cnt=0,pCnt=4;
-
chara[100];
-
charstr[100];
-
doublex=0,y=0,z=0;
- Vec3ftPoint;
- Vector<Vec3f>pointList;
-
- ifstreamin;
- in.open(cfilename,ios::in);
-
if(!in)
- {
-
returnfalse;
- }
- 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)
- {
- tPoint.SetParam(x,y,z);
- pointList.push_back(tPoint);
- }
- pCnt++;
- }while(!in.eof());
-
-
returntrue;
- }
-
-
boolReadBinary(constchar*cfilename)
- {
-
charstr[80];
-
- ifstreamin;
-
intunTriangles(0);
- in.open(cfilename,ios::in);
-
-
if(!in)
- {
-
returnfalse;
- }
-
- in.read(str,80);
-
- in>>unTriangles;
-
-
if(unTriangles==0)
- {
-
returnfalse;
- }
-
- Vec3ftPoint;
- vector<Vec3f>pointList(unTriangles);
-
floatx(0.f),y(0.f),z(0.f);
-
charunusedByte;
-
for(inti=0;i<(int)unTriangles;i++)
- {
-
for(intpointIdx=0;pointIdx<4;pointIdx++)
- {
- in>>x>>y>>z;
- tPoint.SetParam(x,y,z);
- pointList.push_back(tPoint);
- }
-
- in>>unusedByte>>unusedByte;
- }
-
- in.close();
-
-
returntrue;
- }
bool ReadASCII(const char *cfilename)
{
int i=0,j=0,cnt=0 ,pCnt=4;
char a[100];
char str[100];
double x=0,y=0,z=0;
Vec3f tPoint;
Vector<Vec3f> pointList; // todo: 可以预先计算出pointList的大小,节省空间
ifstream in;
in.open(cfilename, ios::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)
{
tPoint.SetParam(x,y,z);
pointList.push_back(tPoint);
}
pCnt++;
}while(!in.eof());
return true;
}
bool ReadBinary(const char *cfilename)
{
char str[80];
ifstream in;
//三角形数目
int unTriangles(0);
in.open(cfilename, ios::in);
if (!in)
{
return false;
}
in.read(str, 80);
in >> unTriangles;
if(unTriangles==0)
{
return false;
}
Vec3f tPoint;
vector<Vec3f> pointList(unTriangles); // 预留足够的空间
float x(0.f), y(0.f), z(0.f);
char unusedByte;
//Binary
for(int i=0;i<(int)unTriangles;i++)
{
for (int pointIdx=0; pointIdx<4; pointIdx++)
{
in >> x >> y >> z;
tPoint.SetParam(x, y, z);
pointList.push_back(tPoint);
}
in >> unusedByte >> unusedByte;
}
in.close();
return true;
}
分享到:
相关推荐
C# anyCAD三维图形显示(STL文件的读取) 实现功能: 1.三维点数据的导入及显示 2.简单画图
用三维CAD软件画了一个轮胎的三维模型,并生成了STL文件,已包含在文件夹中了。当然,你也可以重新画三维模型,替换这个STL文件,同样要显示在本程序中。
stl模型数据在三维场景渲染显示stl模型数据在三维场景渲染显示stl模型数据在三维场景渲染显示stl模型数据在三维场景渲染显示stl模型数据在三维场景渲染显示stl模型数据在三维场景渲染显示stl模型数据在三维场景渲染...
用于STL文件读取与显示的C语言程序,简单方便实用。
将stl三维格式导入MATLAB程序,即可看到三维图像。
c++基于vtk8.1写的三维重建程序,可以读取obj stl等格式文件,重建表面,最后将结果文件保存位obj格式
文件夹内包含两个STL格式文件的模型,用于尝试读取。在C#控制台下完成,含有详细注释。
3D 打印数据格式stl 读取程序,用于stl模型三维展示。用matlab编写的。
用于三维光学形貌扫描完成后,生成的stl文件的读取,并形成俯视投影云图
此文件可以将matlab中的的三维图形转换成stl格式输出,同时附带你demo实例
一个病毒的三维网格数据文件,格式为.stl。 可以使用Python,C++,Matlab等软件进行读取编程使用,用于构建3D生物模型。
使用Java语言读取STL格式文件,读取的是ascii文本格式
用三维CAD软件画了一个轮胎的三维模型,并生成了STL文件,已包含在文件夹中了。当然,你也可以重新画三维模型,替换这个STL文件,同样要显示在本程序中。
C++读取STL文件,输出所有三角形的顶点坐标
在matlab中读取点云数据stl文件并在界面显示
STL格式的三维口腔数据,用来可视化等,可用VTK打开,具体代码见https://blog.csdn.net/xs1997/article/details/89056289#comments_15537422
实现anyCAD开发工具对三维点数据的显示,并实现简单画图功能,能够绘制圆形矩形三角形以及特殊的图形(需要导入图形的点数据,这里涉及到图形STL文件的层切,不做赘述)
很多做三维重建的开发人员都需要读取三维数据,这个程序实现了读取三维数据文件(stl文件)的函数,并用opengl显示出来了,很有参考价值的,其中有函数readstlfile就是实现了从stl文件中读取三角面片的数据。
STL文件有文本(asc)和二进制(bin)两种格式。本程序提供了从文本到二进制格式的转换。
用vtk来实现STL的读取,显示,切层。用Qt做的交互界面。可以实现STL的读取,显示。还可以实现图像的沿z轴方向的均分切层。