博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【OpenMesh】使用网格的属性和特征
阅读量:6254 次
发布时间:2019-06-22

本文共 3395 字,大约阅读时间需要 11 分钟。

例子主要展示如何改变位置,法向量,颜色和纹理的数据类型。

在之前的指南中我们学习使用标准属性,通过调用适合的请求方法。不像自定义属性,用户通过传递数据类型到句柄来指定数据类型(比如,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 
#include
// --------------------#include
#include
#include
#ifndef DOXY_IGNORE_THIS// Define my personal traitsstruct MyTraits : OpenMesh::DefaultTraits{// Let Point and Normal be a vector of doublestypedef 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
MyMesh;// ------------------------------------------------------------------ main ----int main(int argc, char **argv){MyMesh mesh;if (argc!=2){std::cerr << "Usage: " << argv[0] << "
\n";return 1;}// Just make sure that point element type is doubleif ( typeid( OpenMesh::vector_traits
::value_type ) != typeid(double) ){std::cerr << "Ouch! ERROR! Data type is wrong!\n";return 1;}// Make sure that normal element type is doubleif ( typeid( OpenMesh::vector_traits
::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 propertymesh.request_face_normals();// load a meshOpenMesh::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 themif ( !opt.check( OpenMesh::IO::Options::VertexNormal ) &&mesh.has_face_normals() && mesh.has_vertex_normals() ){// let the mesh update the normalsmesh.update_normals();}// move all vertices one unit length along it's normal directionfor (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;}

转载地址:http://vstsa.baihongyu.com/

你可能感兴趣的文章
Hibernate的基本配置
查看>>
Python 3.5 安装geohash库后import geohash失败
查看>>
总结100个英文邮件常用例句让你写作无忧
查看>>
css3--之backface-visibility
查看>>
软件需求分析之猫咪记单词
查看>>
good vs evil
查看>>
算法28-----范围求和
查看>>
基于V4L2的视频驱动开发(1)
查看>>
zoj 1008
查看>>
VC++ CArchive及简单的文件操作方法
查看>>
使用canvas制作一个移动端画板
查看>>
android中ListView数据混乱问题
查看>>
QT学习-10/31/2012
查看>>
jQuery File Upload
查看>>
bbb板运行rtems-编写led底层驱动
查看>>
如何从零安装Mysql
查看>>
Appium简介及工作原理
查看>>
IP 类型转换
查看>>
mysql实践1
查看>>
struts2 Preparable接口
查看>>