zoukankan      html  css  js  c++  java
  • 【OpenMesh】使用网格的属性和特征

    例子主要展示如何改变位置,法向量,颜色和纹理的数据类型。
    在之前的指南中我们学习使用标准属性,通过调用适合的请求方法。不像自定义属性,用户通过传递数据类型到句柄来指定数据类型(比如,MyMesh::FPropHandleT< int>),标准属性的数据类型定义为网格特征。我们可以和特征一起定制和扩展网格数据结构。我们通过两方面做到这一点。

    • 改变位置(Position),法向量(Normal),颜色(Color),和纹理坐标(Texture coordinate不知道翻译对了没)的数据类型。
    • 扩展网格实体,包括顶点,面,边和Halfedge.

    我们开始吧。每一个定制特性应该继承自默认特性。

    struct MyTraits : OpenMesh::DefaultTraits

    之前提到的,我们可以为基本数据类型改变基础数据结构 MyMesh::Point, MyMesh::Normal, MyMesh::Color, and MyMesh::TexCoord。我们可以使用提供的向量类或者我们使用其他类库提供的类。这里我们简单的替换Position和Normal的默认类型OpenMesh::Vec3f为OpenMesh::Vec3d

    typedef OpenMesh::Vec3d Point;
    typedef OpenMesh::Vec3d Normal;

    (通常,Point和Normal向量最好用相同的标量类型,比如在这里使用double型。不然我们将要必须考虑向量类的实现。)
    注意,这些设置覆盖父类的特征!正如我们通常继承DefaultTraits,让我们仔细看看。
    实际上,OpenMesh::DefaultTraits仅仅是一个没有内容的类。它只是为Point,Normal,TexCoord和Color以及一个属性定义了类型,我们一直隐式地使用它们:

    // HalfedgeAttributes( OpenMesh::Attributes::PrevHalfedge );

    属性PrevHalfedge是不同的,因为它没有控制属性。然而,它对网格类型的最终结果有个很大的影响,因为它在Halfedge结构中添加了额外的信息。影响有两点:
    快速地访问前一个Halfedge
    添加内存消耗(居然不是一个优点……)
    使用这个特点取决于我们的需要。一种情况是我们需要访问前一个Halfedge非常便利,这是网格的成员变量函数add_face().当前一个Halfedge可用的时候,成员函数的执行时间迅速下降。通常我们希望有这个信息。但是为了节约内存,我们可以轻松的移除这个特性

    // HalfedgeAttributes( OpenMesh::Attributes::None );

    然后我们需要少于8Byte的空间存储一条边,这就节省很多了,通过欧拉方程可以知道V-E+F=2(1-g),对于一个三角形网格,g=0,边的数目几乎是三倍的顶点数,既E=3V。
    完整的代码:

    #include <iostream>
    #include <typeinfo>
    // --------------------
    #include <OpenMesh/Core/IO/MeshIO.hh>
    #include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>
    #include <OpenMesh/Core/Geometry/VectorT.hh>
    #ifndef DOXY_IGNORE_THIS
    // Define my personal traits
    struct MyTraits : OpenMesh::DefaultTraits
    {
    // Let Point and Normal be a vector of doubles
    typedef OpenMesh::Vec3d Point;
    typedef OpenMesh::Vec3d Normal;
    // Already defined in OpenMesh::DefaultTraits
    // HalfedgeAttributes( OpenMesh::Attributes::PrevHalfedge );
    
    // Uncomment next line to disable attribute PrevHalfedge
    // HalfedgeAttributes( OpenMesh::Attributes::None );
    //
    // or
    //
    // HalfedgeAttributes( 0 );
    };
    #endif
    // Define my mesh with the new traits!
    typedef OpenMesh::TriMesh_ArrayKernelT<MyTraits> MyMesh;
    // ------------------------------------------------------------------ main ----
    int main(int argc, char **argv)
    {
    MyMesh mesh;
    if (argc!=2)
    {
    std::cerr << "Usage: " << argv[0] << " <input>
    ";
    return 1;
    }
    // Just make sure that point element type is double
    if ( typeid( OpenMesh::vector_traits<MyMesh::Point>::value_type ) 
    != typeid(double) )
    {
    std::cerr << "Ouch! ERROR! Data type is wrong!
    ";
    return 1;
    }
    // Make sure that normal element type is double
    if ( typeid( OpenMesh::vector_traits<MyMesh::Normal>::value_type ) 
    != typeid(double) )
    {
    std::cerr << "Ouch! ERROR! Data type is wrong!
    ";
    return 1;
    }
    // Add vertex normals as default property (ref. previous tutorial)
    mesh.request_vertex_normals();
    // Add face normals as default property
    mesh.request_face_normals();
    // load a mesh
    OpenMesh::IO::Options opt;
    if ( ! OpenMesh::IO::read_mesh(mesh,argv[1], opt))
    {
    std::cerr << "Error loading mesh from file " << argv[1] << std::endl;
    return 1;
    }
    // If the file did not provide vertex normals, then calculate them
    if ( !opt.check( OpenMesh::IO::Options::VertexNormal ) &&
    mesh.has_face_normals() && mesh.has_vertex_normals() )
    {
    // let the mesh update the normals
    mesh.update_normals();
    }
    // move all vertices one unit length along it's normal direction
    for (MyMesh::VertexIter v_it = mesh.vertices_begin();
    v_it != mesh.vertices_end(); ++v_it)
    {
    std::cout << "Vertex #" << v_it << ": " << mesh.point( v_it );
    mesh.set_point( v_it, mesh.point(v_it)+mesh.normal(v_it) );
    std::cout << " moved to " << mesh.point( v_it ) << std::endl;
    }
    return 0;
    }



  • 相关阅读:
    枚举、函数关于oracle函数listagg的使用说明by小雨
    执行、Mongodb MapReduce示例1个by小雨
    事务、异常TSQL 编码时应该注意的10个问题by小雨
    源、执行GoldenGate 单向DDL同步by小雨
    Oracle中的所有权限by小雨
    数据库、版本数据库学习从此开始by小雨
    统计、案例深入理解Oracle索引(10):索引列字符类型统计信息的32位限制by小雨
    字段、数据库表三大范式及存储方式by小雨
    数据库、用户第二章Getting Start with the Oracle Server(oracle入门)by小雨
    搜索、关键字截图留念,“万能数据库查询分析器”作为关键字在百度和谷歌上的海量搜索结果by小雨
  • 原文地址:https://www.cnblogs.com/dyllove98/p/3202845.html
Copyright © 2011-2022 走看看