`
chinamming
  • 浏览: 140030 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

三维图形数据格式 STL的 读取

 
阅读更多

在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;

用于存放点坐标数据和法向量数据,这里将点坐标和法向量都读到一个数组中。

  1. boolReadSTLFile(constchar*cfilename)
  2. {
  3. if(cfilename==NULL)
  4. {
  5. returnfalse;
  6. }
  7. ifstreamin(cfilename,ios::in);
  8. if(!in)
  9. {
  10. returnfalse;
  11. }
  12. stringheadStr;
  13. getline(in,headStr,'');
  14. in.close();
  15. if(headStr.empty())
  16. {
  17. returnfalse;
  18. }
  19. if(headStr[0]=='s')
  20. {
  21. ReadASCII(cfilename);
  22. }
  23. else
  24. {
  25. ReadBinary(cfilename);
  26. }
  27. returntrue;
  28. }
  1. boolReadASCII(constchar*cfilename)
  2. {
  3. inti=0,j=0,cnt=0,pCnt=4;
  4. chara[100];
  5. charstr[100];
  6. doublex=0,y=0,z=0;
  7. Vec3ftPoint;
  8. Vector<Vec3f>pointList;//todo:可以预先计算出pointList的大小,节省空间
  9. ifstreamin;
  10. in.open(cfilename,ios::in);
  11. if(!in)
  12. {
  13. returnfalse;
  14. }
  15. do
  16. {
  17. i=0;
  18. cnt=0;
  19. in.getline(a,100,'\n');
  20. while(a[i]!='\0')
  21. {
  22. if(!islower((int)a[i])&&!isupper((int)a[i])&&a[i]!='')
  23. break;
  24. cnt++;
  25. i++;
  26. }
  27. while(a[cnt]!='\0')
  28. {
  29. str[j]=a[cnt];
  30. cnt++;
  31. j++;
  32. }
  33. str[j]='\0';
  34. j=0;
  35. if(sscanf(str,"%lf%lf%lf",&x,&y,&z)==3)
  36. {
  37. tPoint.SetParam(x,y,z);
  38. pointList.push_back(tPoint);
  39. }
  40. pCnt++;
  41. }while(!in.eof());
  42. returntrue;
  43. }
  44. boolReadBinary(constchar*cfilename)
  45. {
  46. charstr[80];
  47. ifstreamin;
  48. //三角形数目
  49. intunTriangles(0);
  50. in.open(cfilename,ios::in);
  51. if(!in)
  52. {
  53. returnfalse;
  54. }
  55. in.read(str,80);
  56. in>>unTriangles;
  57. if(unTriangles==0)
  58. {
  59. returnfalse;
  60. }
  61. Vec3ftPoint;
  62. vector<Vec3f>pointList(unTriangles);//预留足够的空间
  63. floatx(0.f),y(0.f),z(0.f);
  64. charunusedByte;
  65. //Binary
  66. for(inti=0;i<(int)unTriangles;i++)
  67. {
  68. for(intpointIdx=0;pointIdx<4;pointIdx++)
  69. {
  70. in>>x>>y>>z;
  71. tPoint.SetParam(x,y,z);
  72. pointList.push_back(tPoint);
  73. }
  74. in>>unusedByte>>unusedByte;
  75. }
  76. in.close();
  77. returntrue;
  78. }
更多0

在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;

用于存放点坐标数据和法向量数据,这里将点坐标和法向量都读到一个数组中。

  1. boolReadSTLFile(constchar*cfilename)
  2. {
  3. if(cfilename==NULL)
  4. {
  5. returnfalse;
  6. }
  7. ifstreamin(cfilename,ios::in);
  8. if(!in)
  9. {
  10. returnfalse;
  11. }
  12. stringheadStr;
  13. getline(in,headStr,'');
  14. in.close();
  15. if(headStr.empty())
  16. {
  17. returnfalse;
  18. }
  19. if(headStr[0]=='s')
  20. {
  21. ReadASCII(cfilename);
  22. }
  23. else
  24. {
  25. ReadBinary(cfilename);
  26. }
  27. returntrue;
  28. }
  1. boolReadASCII(constchar*cfilename)
  2. {
  3. inti=0,j=0,cnt=0,pCnt=4;
  4. chara[100];
  5. charstr[100];
  6. doublex=0,y=0,z=0;
  7. Vec3ftPoint;
  8. Vector<Vec3f>pointList;//todo:可以预先计算出pointList的大小,节省空间
  9. ifstreamin;
  10. in.open(cfilename,ios::in);
  11. if(!in)
  12. {
  13. returnfalse;
  14. }
  15. do
  16. {
  17. i=0;
  18. cnt=0;
  19. in.getline(a,100,'\n');
  20. while(a[i]!='\0')
  21. {
  22. if(!islower((int)a[i])&&!isupper((int)a[i])&&a[i]!='')
  23. break;
  24. cnt++;
  25. i++;
  26. }
  27. while(a[cnt]!='\0')
  28. {
  29. str[j]=a[cnt];
  30. cnt++;
  31. j++;
  32. }
  33. str[j]='\0';
  34. j=0;
  35. if(sscanf(str,"%lf%lf%lf",&x,&y,&z)==3)
  36. {
  37. tPoint.SetParam(x,y,z);
  38. pointList.push_back(tPoint);
  39. }
  40. pCnt++;
  41. }while(!in.eof());
  42. returntrue;
  43. }
  44. boolReadBinary(constchar*cfilename)
  45. {
  46. charstr[80];
  47. ifstreamin;
  48. //三角形数目
  49. intunTriangles(0);
  50. in.open(cfilename,ios::in);
  51. if(!in)
  52. {
  53. returnfalse;
  54. }
  55. in.read(str,80);
  56. in>>unTriangles;
  57. if(unTriangles==0)
  58. {
  59. returnfalse;
  60. }
  61. Vec3ftPoint;
  62. vector<Vec3f>pointList(unTriangles);//预留足够的空间
  63. floatx(0.f),y(0.f),z(0.f);
  64. charunusedByte;
  65. //Binary
  66. for(inti=0;i<(int)unTriangles;i++)
  67. {
  68. for(intpointIdx=0;pointIdx<4;pointIdx++)
  69. {
  70. in>>x>>y>>z;
  71. tPoint.SetParam(x,y,z);
  72. pointList.push_back(tPoint);
  73. }
  74. in>>unusedByte>>unusedByte;
  75. }
  76. in.close();
  77. returntrue;
  78. }
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics