将*.STL转换成顶点索引格式

将*.STL转换成顶点索引格式

*.stl的格式很简单,某一个片断如下:

solid ascii
  facet normal 0.000000e+000 0.000000e+000 1.000000e+000
    outer loop
      vertex   4.104528e+002 6.994522e+002 0.000000e+000
      vertex   3.895472e+002 6.994522e+002 0.000000e+000
      vertex   4.309017e+002 6.951057e+002 0.000000e+000
    endloop
  endfacet
  facet normal 0.000000e+000 0.000000e+000 1.000000e+000
    outer loop
      vertex   4.309017e+002 6.951057e+002 0.000000e+000
      vertex   3.895472e+002 6.994522e+002 0.000000e+000
      vertex   3.690983e+002 6.951057e+002 0.000000e+000
    endloop
  endfacet
endsolid

可以看出,每个面都是一个三角形,有三个顶点。相邻的面有重复的顶点。若不消除重复的顶点,索引格式实现起来很简单,只需把所有面的顶点取出来,然后分配面的索引即可。若需要消除重复的顶点,那么确定面的顶点索引将十分麻烦。因此,在次将不消除重复的顶点,并忽略面的法向量。。

分析过程分两步:

1)读取顶点数据

2)生成索引式

Point3DList m_PointsList;
POINT3D  m_minPoint;   
POINT3D  m_maxPoint;
POINT3D  m_size;

bool ReadSTL(const char* stlFileName)
{
 FILE*  pSTLFile = fopen(stlFileName, "rt");
 if(NULL == pSTLFile)
  return false;

 m_PointsList.clear();
 m_minPoint.x = m_minPoint.y = m_minPoint.z = 10000;
 m_maxPoint.x = m_maxPoint.y = m_maxPoint.z = -10000;
 
 char strBuffer[BUF_SIZ];
 POINT3D   pointTemp;
 char strTemp[BUF_SIZ];
 int  nPtCount = 0;
 //---------------------------
 // read from stl file
 //---------------------------
 while(fgets(strBuffer, BUF_SIZ, pSTLFile) != NULL)
 {
  memset(strTemp, 0, BUF_SIZ);
  int rlt = sscanf(strBuffer, "%s %lf %lf %lf",
   strTemp, &pointTemp.x, &pointTemp.y, &pointTemp.z);

  if(EOF != rlt)
  {
   if(0 == strcmp(strTemp, "vertex"))
   {
    // min
    if(pointTemp.x < m_minPoint.x)
    {
     m_minPoint.x = pointTemp.x;
    }

    if(pointTemp.y < m_minPoint.y)
    {
     m_minPoint.y = pointTemp.y;
    }

    if(pointTemp.z < m_minPoint.z)
    {
     m_minPoint.z = pointTemp.z;
    }
    
    // max
    if(pointTemp.x > m_maxPoint.x)
    {
     m_maxPoint.x = pointTemp.x;
    }

    if(pointTemp.y > m_maxPoint.y)
    {
     m_maxPoint.y = pointTemp.y;
    }

    if(pointTemp.z > m_maxPoint.z)
    {
     m_maxPoint.z = pointTemp.z;
    }

    nPtCount++;
    m_PointsList.push_back(pointTemp);
    if(nPtCount % 3 == 0)
     m_PointsList.push_back(pointTemp);
   }
   else
   {
    continue;
   }
  }
 }
 fclose(pSTLFile);
 
 // compute size
 m_size.x = m_maxPoint.x - m_minPoint.x;
 m_size.y = m_maxPoint.y - m_minPoint.y;
 m_size.z = m_maxPoint.z - m_minPoint.z;
 if(m_size.x < 1.000000E-10)
  m_size.x = 1.000000E-10;
 if(m_size.y < 1.000000E-10)
  m_size.y = 1.000000E-10;
 if(m_size.z < 1.000000E-10)
  m_size.z = 1.000000E-10;
 
 return true;
}

bool WritePhonDat(const char* dataFileName)
{
 //-----------------------------------
 // write phon data file
 //-----------------------------------
 FILE* pOut = fopen(dataFileName, "wt");
 if(pOut == NULL)
  return false;
 
 char strTemp[BUF_SIZ];

 // position
 memset(strTemp, 0, BUF_SIZ);
 _snprintf(strTemp, BUF_SIZ, " POSITION,  %.6E,  %.6E,  %.6E/n",
  m_minPoint.x, m_minPoint.y, m_minPoint.z);
 fputs(strTemp, pOut);

 // size
 memset(strTemp, 0, BUF_SIZ);
 _snprintf(strTemp, BUF_SIZ, "SIZE    ,  %.6E,  %.6E,  %.6E/n",
  m_size.x, m_size.y , m_size.z);
 fputs(strTemp, pOut);

 // vertex number
 int nVerNum = m_PointsList.size();
 memset(strTemp, 0, BUF_SIZ);
 _snprintf(strTemp, BUF_SIZ, "%6d/n", nVerNum);
 fputs(strTemp, pOut);
 
 // vertex
 Point3DList::iterator it = m_PointsList.begin();
 Point3DList::iterator itEnd = m_PointsList.end();
 for(; it != itEnd; ++it)
 {
  memset(strTemp, 0, BUF_SIZ);
  _snprintf(strTemp, BUF_SIZ, "%.6E %.6E %.6E/n",
   ((*it).x - m_minPoint.x)/m_size.x,
   ((*it).y - m_minPoint.y)/m_size.y,
   ((*it).z - m_minPoint.z)/m_size.z);
  fputs(strTemp, pOut);
 }

 // faces number
 memset(strTemp, 0, BUF_SIZ);
 _snprintf(strTemp, BUF_SIZ, "%6d/n", nVerNum/3);
 fputs(strTemp, pOut);

 // faces index
 for(int i=1; i <= nVerNum; i=i+3)
 {;
  memset(strTemp, 0, BUF_SIZ);
  _snprintf(strTemp, BUF_SIZ, "%6d %6d %6d/n", i, i+1, i+2t);
  fputs(strTemp, pOut);
 }
 
 // end
 
 fclose(pOut); 
 return true;
}

posted on 2005-09-20 15:26  张大大123  阅读(278)  评论(0编辑  收藏  举报

导航