IO的选项使用

在读/写网格时可以使用OpenMesh :: IO :: Options类。 它通过位集中的启用/禁用位控制读写器模块的行为。 该类提供了一个用于启用,禁用和验证集合中的位的接口。 我们区分如下:

这些位在读取或写入时具有不同的效果。 文件格式本身由文件名的扩展名选择。

请注意,每个网格必须在加载相应选项之前请求标准属性。 例如,如果启用Options :: VertexNormal,则网格必须请求顶点法线。 否则,它们将不会被写入网格中。

Face Tex Coords不会被保存为每个面的属性,而是作为每个半边的属性。 因此,您必须请求“halfedge_texcoords2D”属性。

OBJ阅读器还可以读取* .mtl文件中有关纹理的信息(如果有)。 这些纹理信息(包括texturename和index)将保存在类型的属性中:

如果找到纹理,将自动创建此属性。 除了属性请求旁边,您无需定义其他选项来读取纹理信息。此外,如果请求属性“face_texture_index”,OBJ加载程序会在每个面上写入纹理索引。 纹理索引与纹理映射中写入的索引相同。 因此,可以通过纹理映射属性上的纹理索引到纹理名称,从面部获取纹理的名称。 但请记住,在加载网格之前,必须首先请求面纹理索引属性。

在下表中,您可以看到哪些读取器/写入器支持哪些选项(数据格式可能支持更多)。 ASCII不是一个真正的选项,如果没有定义二进制,将被选中。

*)可以读取非标准扩展顶点颜色(仅浮动):

**)只有具有基本类型的顶点和面属性。 请注意,您不必在加载前请求这些自定义属性。

***)没有读取操作存在。

Reading meshes

  • 在读取文件时,模式位用于向读者提供建议或提示。 根据格式,我们可以帮助读者正确解释数据。 首先,我们可以告诉它该文件包含二进制数据。
  • 此外,我们可以要求读者两个交换字节顺序。
  • 默认情况下,将从文件中恢复几何体和拓扑。 该文件可能包含更多,特别是它可以提供法线或纹理坐标。 我们可以在阅读后检查属性位以找出可用的其他内容:
  • 如果设置了属性位,那么它并不意味着它已经被恢复。 必须在阅读文件之前请求该属性。 

Writing meshes

  • 在写入网格时,模式位显然控制是否使用二进制变量和所需的字节顺序。 例如,如果我们选择二进制模式并想要交换字节顺序,我们设置
  • 如果格式未指定字节顺序,则使用系统字节顺序。 如果格式不支持二进制存储,则忽略模式位。
  • 如果格式支持存储符合标准属性的附加信息,我们可以使用属性位来告诉作者我们想要存储的内容。 如果我们想存储顶点法线,我们只需设置
  • 最后,我们可以将数据写入文件
  • 该方法在出错时返回false,这可能有三个不同的原因:
  1. 选择的格式不支持该选项
  2. 选定的标准属性不可用
  3. 一个'系统'错误就像:由于访问权限无法打开文件、写入期间磁盘空间耗尽

完整的源代码如下所示:

#include <iostream>
#include <iterator>
// -------------------- OpenMesh
#include <OpenMesh/Core/IO/MeshIO.hh>
#include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>
#include <OpenMesh/Tools/Utils/getopt.h>
// ----------------------------------------------------------------------------
using namespace OpenMesh;
// ----------------------------------------------------------------------------
typedef TriMesh_ArrayKernelT<>  MyMesh;
// ----------------------------------------------------------------------------
#define CHKROPT( Option ) \
  std::cout << "  provides " << #Option \
            << (ropt.check(IO::Options:: Option)?": yes\n":": no\n")
#define CHKWOPT( Option ) \
  std::cout << "  write " << #Option \
            << (wopt.check(IO::Options:: Option)?": yes\n":": no\n")
#define MESHOPT( msg, tf ) \
  std::cout << "  " << msg << ": " << ((tf)?"yes\n":"no\n")
// ----------------------------------------------------------------------------
void parse_commandline( int _argc, char **_argv, MyMesh& _mesh,
                        IO::Options &ropt, IO::Options &wopt );
void usage_and_exit(int xcode);
// ----------------------------------------------------------------------------
int main(int argc, char **argv)
{
  MyMesh  mesh;
  IO::Options ropt, wopt;
  // -------------------- evaluate commandline
  parse_commandline( argc, argv, mesh, ropt, wopt );
  // -------------------- read mesh
  if ( ! IO::read_mesh(mesh,argv[optind], ropt))
  {
    std::cerr << "Error loading mesh from file " << argv[optind] << std::endl;
    return 1;
  }
  // -------------------- show options
  std::cout << "File " << argv[optind] << std::endl;
  std::cout << "  is binary: " 
            << (ropt.check(IO::Options::Binary) ? " yes\n" : " no\n");
  std::cout << "  byte order: ";
  if (ropt.check(IO::Options::Swap))
    std::cout << "swapped\n";
  else if (ropt.check(IO::Options::LSB))
    std::cout << "little endian\n";
  else if (ropt.check(IO::Options::MSB))
    std::cout << "big endian\n";
  else
    std::cout << "don't care\n";
  
  std::cout << "  provides VertexNormal"
            << ( // strange layout for doxygen
                ropt.check(IO::Options::VertexNormal) 
                ? ": yes\n":": no\n");
  CHKROPT( VertexColor    );
  CHKROPT( VertexTexCoord );
  CHKROPT( FaceNormal     );
  CHKROPT( FaceColor      );
  // -------------------- mesh stats
  std::cout << "# Vertices: " << mesh.n_vertices() << std::endl;
  std::cout << "# Edges   : " << mesh.n_faces() << std::endl;
  std::cout << "# Faces   : " << mesh.n_faces() << std::endl;
  // -------------------- show write options
  std::cout << "Selected write options:\n";
  std::cout << "  use binary: " 
            << (wopt.check(IO::Options::Binary) ? " yes\n" : " no\n");
  std::cout << "  byte order: ";
  if (wopt.check(IO::Options::Swap))
    std::cout << "swapped\n";
  else if (wopt.check(IO::Options::LSB))
    std::cout << "little endian\n";
  else if (wopt.check(IO::Options::MSB))
    std::cout << "big endian\n";
  else
    std::cout << "don't care\n";
  
  std::cout << "  write VertexNormal"
            << (wopt.check(IO::Options::VertexNormal) ? ": yes\n":": no\n");
  CHKWOPT( VertexColor    );
  CHKWOPT( VertexTexCoord );
  CHKWOPT( FaceNormal     );
  CHKWOPT( FaceColor      );
  // -------------------- show mesh capabilities
  std::cout << "Mesh supports\n";
  MESHOPT("vertex normals", mesh.has_vertex_normals());
  MESHOPT("vertex colors", mesh.has_vertex_colors());
  MESHOPT("texcoords", mesh.has_vertex_texcoords2D());
  MESHOPT("face normals", mesh.has_face_normals());
  MESHOPT("face colors", mesh.has_face_colors());
  // -------------------- write mesh
  std::cout << "Write mesh to " << argv[optind+1] << "..";
  if ( !IO::write_mesh( mesh, argv[optind+1], wopt ) )
  {
    std::cerr << "Error" << std::endl;
    std::cerr << "Possible reasons:\n";
    std::cerr << "1. Chosen format cannot handle an option!\n";
    std::cerr << "2. Mesh does not provide necessary information!\n";
    std::cerr << "3. Or simply cannot open file for writing!\n";
    return 1;
  }
  else
    std::cout << "Ok.\n";
  return 0;
}
// ----------------------------------------------------------------------------
void parse_commandline( int _argc, char **_argv, MyMesh& _mesh,
                        IO::Options &ropt, IO::Options &wopt )
{
  int c;
  while ((c=getopt(_argc, _argv, "bhsBF:LMSV:X:"))!=-1)
  {
    switch(c) 
    {
      // -------------------- read options
      // force binary input
      case 'b': 
        ropt += IO::Options::Binary; 
        break;
      // force swapping the byte order, when reading a binary file
      case 's': 
        ropt += IO::Options::Swap; 
        break;
      // -------------------- write options
      // Write binary variant of format if possible
      case 'B': 
        wopt += IO::Options::Binary; 
        break;
      // 
      case 'F':
        for(size_t i=0; optarg[i]; ++i)
          switch(optarg[i]) {
            case 'n' : wopt += IO::Options::FaceNormal; break;
            case 'c' : wopt += IO::Options::FaceColor; break;
          }
        break;
      // Use little endian when writing binary data
      case 'L': 
        wopt += IO::Options::LSB; 
        break;
      // Use big endian when writing binary data
      case 'M': 
        wopt += IO::Options::MSB; 
        break;
      // Swap byte order when writing binary data
      case 'S': 
        wopt += IO::Options::Swap; 
        break;
      //
      case 'V':
      {
        for(size_t i=0; optarg[i]; ++i)
          switch(optarg[i]) {
            case 'n' : // dont't change layout!!
              wopt += IO::Options::VertexNormal; 
              break;
            case 't' : wopt += IO::Options::VertexTexCoord; break;
            case 'c' : wopt += IO::Options::VertexColor; break;
          }
        break;
      }
      // -------------------- request mesh' standard properties
      case 'X':
      {        
        char entity='\0';
        for(size_t i=0; optarg[i]; ++i)
          switch(optarg[i]) {
            case 'v': 
            case 'f': entity = optarg[i]; break;
            case 'n':
              switch(entity) {
                case 'v': _mesh.request_vertex_normals(); break;
                case 'f': _mesh.request_face_normals(); break;
              }
              break;
            case 'c':
              switch(entity) {
                case 'v': _mesh.request_vertex_colors(); break;
                case 'f': _mesh.request_face_colors(); break;
              }
              break;
            case 't':
              switch(entity) {
                case 'v': _mesh.request_vertex_texcoords2D(); break;
              }
              break;
          }
        break;
      }
      
      // -------------------- help
      case 'h':
        usage_and_exit(0);
      default:
        usage_and_exit(1);
    }
  }
  if ( _argc-optind != 2)
    usage_and_exit(1);
}
// ----------------------------------------------------------------------------
void usage_and_exit(int xcode)
{
  std::ostream &os = xcode ? std::cerr : std::cout;
  os << "Usage: io_options [Options] <input> <output>\n" 
     << std::endl;
  os << "  Read and write a mesh, using OpenMesh::IO::Options\n"
     << std::endl;
  os << "Options:\n"
     << std::endl;
  os << "a) read options\n"
     << std::endl
     << "  -b\n"
     << "\tAssume input file is a binary file\n"
     << std::endl
     << "  -s\n"
     << "\tSwap byte order when reading a binary file!\n"
     << std::endl;
  os << "b) write options\n"
     << std::endl
     << "  -B\n"
     << "\tWrite binary data\n"
     << std::endl
     << "  -S\n"
     << "\tSwap byte order, when writing binary data\n"
     << std::endl
     << "  -M/-L\n"
     << "\tUse MSB/LSB byte ordering, when writing binary data\n"
     << std::endl
     << "  -V{n|t|c}\n"
     << "\tWrite vertex normals, texcoords, and/or colors\n"
     << std::endl
     << "  -F{n|c}\n"
     << "\tWrite face normals, and/or colors\n"
     << std::endl;
  os << "c) Mesh properties\n"
     << std::endl
     << "  -Xv{n|c|t}\n"
     << "\tRequest vertex property normals|colors|texcoords\n"
     << std::endl
     << "  -Xf{n|c}\n"
     << "\tRequest face property normals|colors\n"
     << std::endl;
  exit(xcode);
}
// end of file
// ============================================================================

 

使用 PlatformIO,您可以按照以下步骤进行操作: 1. 安装 PlatformIO:首先,您需要安装 PlatformIO 的开发环境。您可以选择安装 PlatformIO IDE(基于 Visual Studio Code 或 Atom)或 PlatformIO Core(命令行工具)。您可以访问 PlatformIO 的官方网站(https://platformio.org/)下载并按照指导进行安装。 2. 创建项目:使用 PlatformIO,您可以创建一个新的项目或导入现有的项目。在 IDE 中,您可以选择 "New Project" 或 "Import Project" 选项,并按照指导进行操作。 3. 配置项目:在创建或导入项目后,您需要配置项目的环境和硬件平台。选择适合您的硬件平台(如 Arduino、Raspberry Pi 等)和开发板,并设置相关的编译器选项、串口设置等。 4. 编写代码:使用 PlatformIO,您可以使用 C/C++ 或其他支持的编程语言编写嵌入式代码。在项目中的 src 文件夹中创建您的代码文件,并开始编写代码。 5. 构建和调试:使用 PlatformIO,您可以构建和调试您的项目。在 IDE 中,选择相应的构建和调试选项,并进行必要的设置。 6. 上传到设备:一旦您的代码编译成功,您可以将代码上传到目标设备。根据您的硬件平台和开发板,选择适当的上传方法(如串口、无线上传等)。 7. 调试和测试:通过 PlatformIO,您可以进行代码的调试和测试。您可以设置断点、监视变量、单步执行等来调试您的代码。 8. 打包和发布:如果您希望与他人共享您的项目,您可以使用 PlatformIO 打包和发布您的项目。这样其他人就可以轻松地导入和使用您的代码。 以上是使用 PlatformIO 的一般步骤。具体操作可以根据您的项目需求和硬件平台进行调整。您可以参考 PlatformIO 的官方文档和社区支持获取更多信息和帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值