例子主要展示如何改变位置,法向量,颜色和纹理的数据类型。
在之前的指南中我们学习使用标准属性,通过调用适合的请求方法。不像自定义属性,用户通过传递数据类型到句柄来指定数据类型(比如,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>\n";
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!\n";
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!\n";
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;
}

【OpenMesh】使用网格的属性和特征的更多相关文章

  1. OpenMesh 读写网格控制(读取写入纹理坐标,法向等)

    OpenMesh读取网格默认是不自动读取obj网格中的法向,纹理坐标等信息的,写入网格同样也是.所以要读取(或写入)这些信息需要修改默认的选项. 先看一下其读写网格的函数 template<cl ...

  2. 雷林鹏分享:jQuery EasyUI 数据网格 - 创建属性网格

    jQuery EasyUI 数据网格 - 创建属性网格 属性网格(property grid)带有一个内置的 expand(展开)/collapse(合并) 按钮,可以简单地为行分组.您可以简单地创建 ...

  3. CSS3 网格布局(grid-layout)基础知识 - 网格模板属性(grid-template)使用说明

    CSS3引入了新的网格布局(grid layout),以适应显示和设计技术的发展(尤其是移动设备优先的响应式设计). 主要目标是建立一个稳定可预料且语义正确的网页布局模式,用来替代过往表现不稳定且繁琐 ...

  4. OpenMesh 删除网格顶点

    OpenMesh 提供了 delete_vertex() 函数来实现从网格中删除顶点,在删除掉顶点的同时,所有与该顶点相连的边也同时被删除. OpenMesh 官方文档 中给的顶点删除函数声明如下: ...

  5. RadioButton 的background属性表现特征

    对于radiaoButton,应该很多人都用过.下面看一个场景     上方时radiogroup,细致观察发现左1,文字开始位置和右1文字开始位置不同,这是为何呢? 查看布局: <RadioB ...

  6. kaggle数据挖掘竞赛初步--Titanic<派生属性&维归约>

    完整代码: https://github.com/cindycindyhi/kaggle-Titanic 特征工程系列: Titanic系列之原始数据分析和数据处理 Titanic系列之数据变换 Ti ...

  7. Unity加载模块深度解析(网格篇)

    在上一篇 加载模块深度解析(一)中,我们重点讨论了纹理资源的加载性能.这次,我们再来为你揭开其他主流资源的加载效率. 这是侑虎科技第53篇原创文章,欢迎转发分享,未经作者授权请勿转载.同时如果您有任何 ...

  8. Compounding绑定属性

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  9. 特征的SID表、M表、P表、Q表、X表、Y表、T表

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

随机推荐

  1. CTRL+A, CTRL+C, CTRL+V

    (http://leetcode.com/2011/01/ctrla-ctrlc-ctrlv.html) Imagine you have a special keyboard with the fo ...

  2. cocos2dx vs2010打开打印窗口

    vs2010下调试时,有时需要有打印窗口. 在main.cpp函数的开始处,加入一下 AllocConsole(); freopen("CONIN$", "r" ...

  3. ASP.NET MVC进阶之路:深入理解依赖注入(DI)和控制反转(IOC)

    0X1 什么是依赖注入 依赖注入(Dependency Injection),是这样一个过程:某客户类只依赖于服务类的一个接口,而不依赖于具体服务类,所以客户类只定义一个注入点.在程序运行过程中,客户 ...

  4. Android 百度地图开发问题----解决地图有时候加载不出来问题

    相信很多人在开发百度地图的时候会出现百度地图有时候会加载不出来,只显示网格图. 这个问题究其原因就是申请百度key的时候填写的SHA1也就是指纹证书有问题.估计很多开发者都是照着百度开放平台上介绍的流 ...

  5. 【示例代码】HTML+JS 画图板源码分享

    一个有趣的画图板, 用了 HTML5中的本地存储.下载.canvas 等技术,这个项目中用到了canvas 的很多基础功能,初学者可以学习一下 . 建议开发童鞋使用统一开发环境UDE来进行查看.调试. ...

  6. Clojure绘制UML

    简单介绍 使用Clojure封装了Graphviz的使用.眼下主要实现了UML的绘制 使用 以命令模式的UML为例,演示cdraw的使用 安装Graphviz cdraw是对Graphviz的简单封装 ...

  7. EGL接口 简单介绍

    from http://lyodev.appspot.com 第二章 EGL 接口 EGL 是 OpenGL ES 和底层 Native 平台视窗系统之间的接口.本章主要讲述 OpenGL ES 的 ...

  8. C# - String与StringBuilder

    A String object is called immutable (read-only), because its value cannot be modified after it has b ...

  9. hadoop权威指南 chapter1 Meet Hadoop

    Meet Hadoop 1.1 Data!(数据) Most of the data is locked up in the largest web properties (like search e ...

  10. ThinkPHP - 事务操作

    /* * 添加酒店和房型 * */ public function insertAll($arr_hotel=array(),$arr_room=array()){ $model = new Mode ...