源码阅读 | OpenMesh读取文本格式stl的过程

Posted CSU迦叶

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了源码阅读 | OpenMesh读取文本格式stl的过程相关的知识,希望对你有一定的参考价值。

bool
_STLReader_::
read_stla(std::istream& _in, BaseImporter& _bi, Options& _opt) const
//数据流向是从_in到_bi中

  unsigned int               i;
  OpenMesh::Vec3f            v;//存放单个顶点三维坐标的vector容器
  OpenMesh::Vec3f            n;//存放单个法向三维坐标的vector容器
  BaseImporter::VHandles     vhandles;//存放某一三角面片的3个顶点的句柄

  CmpVec comp(eps_);//用来比较顶点是否重合,eps_是一个很小的常量
  std::map<Vec3f, VertexHandle, CmpVec>            vMap(comp);//将顶点坐标容器映射的顶点句柄的集合容器
  std::map<Vec3f, VertexHandle, CmpVec>::iterator  vMapIt;//前一行集合容器的迭代器

  std::string line;//存放输入流中的单行内容

  std::string        garbage;//废弃字符串
  std::stringstream  strstream;//从单行内容中逐个取出字符串

  bool facet_normal(false);//标识一个三角面片是否有法向

  while( _in && !_in.eof() ) //while循环是读取的真正实现

    // Get one line 得到一行内容到line
    std::getline(_in, line);
    if ( _in.bad() )//如果有致命错误
      omerr() << "  Warning! Could not read stream properly!\\n";
      return false;
    

    // Trim Both leading and trailing spaces 删掉之前和之后的空格
    trimStdString(line);

    // Normal found?
    if (line.find("facet normal") != std::string::npos) 
      strstream.str(line);
      strstream.clear();

      // facet字符串丢掉
      strstream >> garbage;

      // normal字符串丢掉
      strstream >> garbage;

      strstream >> n[0];//依次读入面片法向的三维坐标
      strstream >> n[1];
      strstream >> n[2];

      facet_normal = true;
    

    // Detected a triangle 三角面片的三维坐标是以outer loop开头的
    if ( (line.find("outer") != std::string::npos) ||  (line.find("OUTER") != std::string::npos ) ) 

      vhandles.clear();//把上一个面片的顶点句柄清楚

      for (i=0; i<3; ++i) //依次读入三个顶点
        // Get one vertex
        std::getline(_in, line);
        trimStdString(line);// line里面格式类似--vertex 0 0 0

        strstream.str(line);
        strstream.clear();

        strstream >> garbage;//丢掉vertex

        strstream >> v[0];//依次存入当前顶点的三维坐标
        strstream >> v[1];
        strstream >> v[2];

        // has vector been referenced before? 判断该顶点在vMap中是否已经存放
        if ((vMapIt=vMap.find(v)) == vMap.end()) 在vMap中没找到
        
          // No : add vertex and remember idx/vector mapping
          VertexHandle handle = _bi.add_vertex(v);//关键,将顶点的坐标向量添加到_bi中
          vhandles.push_back(handle);//只有这一句else块中也做
          vMap[v] = handle;
        
        else
          // Yes : get index from map
          vhandles.push_back(vMapIt->second);

      

      // Add face only if it is not degenerated 判断一个面是否退化
      if ((vhandles[0] != vhandles[1]) &&
          (vhandles[0] != vhandles[2]) &&
          (vhandles[1] != vhandles[2]))  //该面的三个顶点中有任意两个重合说明面退化
        

        FaceHandle fh = _bi.add_face(vhandles);//将没退化的面添加到_bi中,注意这里的面就是由其三个顶点的句柄指代

        // set the normal if requested
        //如果当前面有法向,则给它设置法向信息
        // if a normal was requested but could not be found we unset the option
        if (facet_normal) 
          if (fh.is_valid() && _opt.face_has_normal())
            _bi.set_normal(fh, n);
         else
          _opt -= Options::FaceNormal;
      

      facet_normal = false;
    
  

  return true;

参考文档 

OpenMesh: OpenMesh::IO::_STLReader_ Class Reference

以上是关于源码阅读 | OpenMesh读取文本格式stl的过程的主要内容,如果未能解决你的问题,请参考以下文章

环境配置 | VS2017配置OpenMesh源码和环境

Python STL csv

如何用java读取ASCII码STL文件

STL源码剖析之allocator

源码阅读笔记 – std::vector 关于Allocator Aware Container特性

如何用vtk读取stl模型获取点