• 将*.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;
    }

  • 相关阅读:
    怎么修改android飞行模式wifi
    斐讯n1盒子装远程迅雷
    Spring使用大全
    面向对象7大设计原则
    Mybatis之SqlNode解析
    【转载】MongoDB的C#驱动程序教程
    【转载】 mongodb C# 基本类库
    【转载】列举MongoDB C#驱动的几个Query方法
    【转载】MongoDB开发学习
    【转载】sql全国省市区数据库建表过程
  • 原文地址:https://www.cnblogs.com/aiwz/p/6333175.html
Copyright © 2020-2023  润新知