构建自定义的网格

有一些参数需要为网格指定。 这是通过以下四个步骤完成的:

  • 选择三角形网格和一般多边形网格。
  • 选择网格内核
  • 通过所谓的Traits类对网格进行参数化。 您可以向网格项添加任意类,指定标量,点,正常和颜色类型,并使用预定义属性,如Attributes :: Normal和Attributes :: Color。
  • 使用自定义属性将数据动态绑定到网格或网格实体(顶点,(半)边,面)。

多边形网格与三角形网格的选择

  • 这个决定很简单:尽可能选择三角形网格。 对三角形面的限制通常导致更有效的算法。 另外,一些算法仅针对三角形网格实现,而三角形网格继承多边形网格的全部功能。

选择正确的内核

  • 网格内核指定网格实体(顶点,(半)边,面)如何在内部存储。 事实上,实体被保存在所谓的属性中。 属性本身提供类似接口的数组。 内核定义了相应的句柄类型,即项目相互引用的方式。 由于属性具有类似接口的数组,因此句柄在内部表示为索引。
  • 默认内核是ArrayKernelT。 这对大多数情况都有好处。 但根据应用程序的不同,内核会更好。

​​​​​​​网格特征

生成的网格MyMesh将提供以下类型:

  • 点和标量类型:MyMesh :: Point和MyMesh :: Scalar。
  • 网格条目:MyMesh :: Vertex,MyMesh :: Halfedge,MyMesh :: Edge,MyMesh :: Face。
  • 句柄类型:MyMesh :: VertexHandle,MyMesh :: HalfedgeHandle,MyMesh :: EdgeHandle,MyMesh :: FaceHandle。

虽然句柄类型是固定的,但其他类型可以自定义。 每种网格类型(参见预定义网格类型)都可以通过所谓的traits类进行参数化。 

  • 更改坐标类型MyMesh :: Point和生成的标量类型MyMesh :: Scalar == MyMesh :: Point :: value_type,
  • 更改正常类型MyMesh :: Normal
  • 更改颜色类型MyMesh :: Color
  • 使用预定义的属性,如法线向量,颜色,纹理坐标,...用于网格项目。
  • 向网格项添加任意类。

所有这些自定义都封装在一个类MyTraits中,该类用作网格的模板参数,例如

对于每个网格实体,可以使用一些便利宏来控制由特征类附加的预定义属性,例如, OpenMesh :: VertexAttributes和OpenMesh :: VertexTraits用于顶点。 默认traits类如下所示:

请注意,例如,VertexTraits是隐藏模板声明的定义。 实际的模板类名称是VertexT,它在构建网格内核的后期进一步简化为特定类型的Vertex。

因为traits类总是必须提供模板类VertexT,HalfedgeT,EdgeT,FaceT以及Point,Normal,Color和TexCoord类型,所以应该从默认实现DefaultTraits派生此类。 在这种情况下,您只需要定义要覆盖或替换的类或类型。

改变点的类型

通过在traits类中定义此类型,可以简单地更改用于存储点坐标以及法线向量的类型。 以下代码更改坐标类型以使用double而不是float。

使用OpenMesh :: VectorT类,您可以轻松插入任何标量类型,以便在点坐标中使用。

添加预定义的属性

  • 有一些预定义的属性可以附加到网格项目。 这些全局属性在命名空间OpenMesh :: Attributes中定义。 这些属性的优点是它们在添加到的项目中注册。 因此,算法可以在运行时和编译时检查这些属性。
  • 添加这些预定义属性非常简单。 您在traits类中提供unsigned int,其位控制是否应附加某个属性。
  • 如果要向顶点和面添加法线向量,并且还希望获得顶点的颜色信息,则代码如下所示:
  • 在内部,每个网格项都包含一个枚举,用于定义整数属性(包含已使用属性的位或“或”)。 从其设置/未设置位,您可以查看是否使用了某个属性。 OpenMesh为此提供宏OM_Check_Attrib:
  • 在某些情况下,这些运行时检查可能还不够。 您还可以在编译时检查属性,并使用函数重载来实例化正确的函数。 GenProg :: Bool2Type类将true / false信息映射到两种不同的类型,Bool2Type <true>和Bool2Type <false>。 如果OpenGL法线可用,则绘制OpenGL法线的示例如下所示:

添加用户定义的元素

您还可以通过为这些项提供相应的traits类,将任意类型/元素/方法添加到网格项中。向Vertex类添加一些索引很容易就像下面的例子:

当您想要为顶点类型定义构造函数或者想要从其他类派生顶点类型时,必须牢记这一点。

模板参数Base通过其成员类Refs提供对网格句柄和Point和Scalar类型的访问。 因此,可以像这样实现将MyMesh :: FaceHandle添加到顶点类:

使用算法定义特征

从版本0.10.3开始,算法可以定义它们需要的特征/属性,用户可以将这些特征合并到他自己的特征中。 更优雅的方法是使用动态属性,可以在运行时通过算法添加/删除动态属性。 这是将自定义数据附加到网格的首选方法。​​​​​​​

示例

  • 考虑一个我们只想渲染三角形网格的应用程序。 这意味着我们将选择三角形网格和ArrayKernelT。 不是三角形的面将自动被分成三角形。 因为我们只显示网格而不动态添加或删除项目,所以我们可以使用ArrayKernelT。
  • #include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>
    // define traits
    struct MyTraits : public OpenMesh::DefaultTraits
    {
      // use double valued coordinates
      typedef OpenMesh::Vec3d Point;
      // use vertex normals and vertex colors
      VertexAttributes( OpenMesh::DefaultAttributer::Normal |
                        OpenMesh::DefaultAttributer::Color );
      // store the previous halfedge
      HalfedgeAttributes( OpenMesh::DefaultAttributer::PrevHalfedge );
      // use face normals
      FaceAttributes( OpenMesh::DefaultAttributer::Normal );
      // store a face handle for each vertex
      VertexTraits
      {
        typename Base::Refs::FaceHandle my_face_handle;
      };
    };
    // Select mesh type (TriMesh) and kernel (ArrayKernel)
    // and define my personal mesh type (MyMesh)
    typedef OpenMesh::TriMesh_ArrayKernelT<MyTraits>  MyMesh;
    int main(int argc, char **argv)
    {
      MyMesh mesh;
      // -------------------- Add dynamic data
      // for each vertex an extra double value
      OpenMesh::VPropHandleT< double > vprop_double;
      mesh.add_property( vprop_double );
      // for the mesh an extra string
      OpenMesh::MPropHandleT< string > mprop_string;
      mesh.add_property( mprop_string );
      // -------------------- do something
      ...;
    }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值