几个经典的数学库之一学习---VCGlib(1)
1. VCG Libary是Visulization and Computer Graphics Libary(可视化与计算机图形学库)的缩写,是一个开源的C++模板库,用于三角网格和四面体网格的控制、处理和OpenGL显示。其中包含了超过100 000行的代码。基于该库,Visual Computing Lab开发了几个著名的工具,如metro和MeshLab。
VCG Libary是专门为处理三角网格而设计的,库很大,且提供了许多最先进的处理网格的功能,如:
*基于边坍塌(edge-collapse)二次误差的高质量网格简化(simplfication);*高效的空间检索数据结构(uniform grids, hashed grids, kdtree, ...);*先进的网格平滑和光顺算法;*曲率计算;*纹理坐标优化;*Hausdorff距离计算;*测地路径;*网格修复能力*等直面抽取和前沿的网格划分算法;*泊松圆盘采样和其他的网格点采样算法;*细分曲面。
VCG Lib的大部分由头文件组成,下载后,将文件解压到一个vcglib文件夹中,然后将vcglib文件夹放到你的编译器的“include”目录中。然后使用时,只要包含其中需要的文件即可。
同上图,vcglib文件夹中,总共包含5个子文件夹:
*vcg:这是整个库的核心,其中定义了所有的算法和数据结构。该部分所有的C++代码都是STL支持的普通数据结构和算法,不包含任何其它标准库之外的库,而且可以发现,该部分只包含头文件(.h);
*wrap:这里包含一些针对特定需求/上下文/库的VCG概念的封装。例如,所有的用于计算机硬盘上很多格式的网格数据的导入和导出;用OpenGL渲染三角形网格的代码;普通GUI工具如跟踪球,等等;
*apps:这个文件夹包含一些用VCG Lib开发的命令行程序应用。很多例子都能在MeshLab中找到,apps/simple文件夹包含了这些程序的一个基础的子集,是一个初学者很好的入口点;
*docs:文档(包括这个教程)
*eigenLib:线性代数的eigen库最近的稳定版本的一个副本(相当于就是借用第三方库了),VCGLib中的高级矩阵操作都是基于这个库的。

图中顶点编号从0到2,以逆时针顺序编号,边i(i=0..2)的两个端点分别为i和(i+1)%3,因此图中面f0和面f1的公共边对f0而言是0边,对f1而言是1边。
对于面f的每个边i,vcg::face::FFAdj存储以下信息:
- FFp(i):指向共享边i的面的指针,若i是border,则该指针指向自己;
- FFi(i):在指向的面中i的索引。在共享边的面中的索引。
例如在上图中,有:
- f1->FFp(1) == f0
- f1->FFi(1) == 0
- f0->FFp(0) == f1
- f0->FFi(0) == 1
需要说明的是, FFp(i)指向一个邻接面。如果是下图中的non-manifld 边的情况,(奇异边)则在一边上有多余两个面。这看起来在VCG中没有支持。
bool IsManifold(MyFace *f,int e) { return (f0 == f0->FFp()->FFp(f0->FFi()))}

Pos关系
三角网格中,Pos为一三元组,pos = {v,e,f},e是f的边,v是e的端点。

下图以小三角形的形式显示了三角网格中的一些pos,在每个面中,每个小三角形指向一个顶点,倚靠一条边,且在一个三角形面片中。
这样就能保证任意给定一个pos c,若只改变c的三元组的一个分量,能够唯一确定一个邻居pos。
C2与C1,的Pos只有Vertex Component不同,即 C2 = FlipV(C1)

c2 = FlipV(c1),定点分量不同,即换顶点则在同一个三角形中同一条边的另一个定点。
c0 = FlipE(c1),边分量不同,即换边则在同一个三角形中同一个定点的另一个边。
c3 = FlipF(c0), 面分量不同,即换面则通过边临街另一个面。 CCW around v,(逆时针旋转V)
c4 = FlipE(FlipF(c0)),即C0换面换边后为C4
c5 = FlipE(FlipF(c4)),即C4换面换边后C5
Bounce(弹跳,遇到边界情况)
c6 = FlipE(FlipF(c5)),遇到边界后弹回
CW around v (顺时针旋转V)
c3 = FlipE(FlipF(c6))
c1 = FlipE(FlipF(c3))
Bounce(弹跳)
c0 = FlipE(FlipF(c1)),遇到边界弹回
当两个flip嵌套操作的时候,根据pos与面的关系,可以实现顺时针或逆时针的pos转换。并且由于面-面邻接关系的定义方式,当pos在border上的时候,FlipF操作会返回到pos本身所在的面。
VCG库中广泛使用成对的flip,mannifold定点的相邻的ring环。
下面的例子使用pos来迭代一个点的周围相关性。
sf/apps/sample/trimesh_pos_demo/trimesh_pos_demo.cpp #include <vcg/simplex/face/pos.h> // include the definition of pos ...includes to define your mesh type class MyVertex: ...
class MyFace: public vcg::FaceSimp2<MyVertex,MyEdge,MyFace, vcg::face::VertexRef, vcg::face::FFAdj>{}; void OneRingNeighborhood( MyFace * f)
{
MyVertex * v = f->V();
MyFace* start = f;
vcg::face::Pos<MyFace> p(f,,v);// constructor that takes face, edge and vertex
do
{
p.FlipF();
p.FlipE();
}while(p.f!=start);
}
注意:
(1)使用属性vcg::vertex::VFAdj属性,可以关联的顶点指针指向面。(2)如果定点再边界上,则上述方法行不通。即从C4开始,将会找到C5,C6,C3,即C3余C4在同一个面中。但是,如果遇到边界,则会“弹”回来,即在这个图中,可能会得到C5,C6,C3, C1,C0, C4的序列,这或许不能够完成对一个定点的便利序列。
VCG提供以下的方法解决
Jumping Pos
Jumping Pos类似Pos,但在遇到border的时候不会反弹回去,而是跨到下一个border-face上去。下面这个例子中,上图中的p会从f0跨到f2。
sf/apps/sample/trimesh_pos_demo/trimesh_pos_demo.cpp
#include <vcg/simplex/face/jumping_pos.h> // include the definition of jumping pos
//...includes to define your mesh type
//class MyVertex: ...
class MyFace: public vcg::FaceSimp2<MyVertex,MyEdge,MyFace, vcg::face::VertexRef,vcg::face::FFAdj>{};
void OneRingNeighborhoodJP( MyFace * f)
{
MyVertex * v = f->V();
MyFace* start = f;
vcg::face::JumpingPos<MyFace> p(f,,v);// constructor that takes face, edge and vertex
do
{
p.NextFE();
}while(p.f!=start);
}
2. VF Adjacency(顶点-面, Vertex-Face 邻接关系)
VCG lib中,顶点与面之间也实现了邻接关系,即给定一个顶点v,可以找出所有与其关联的面。
设v_star = (f0,f1,f2,…,fk)为一个列表,该列表中的元素都是与顶点v关联的面。可以通过以下属性索引v_star:
- vcg::vertex::VFAdj:这是一个顶点的属性,包含了指向f0的指针
- vcg::face::VFAdj:这是面的属性,该面三个顶点中的每一个顶点都包含了指向v_star列表中下一个面的指针

这两个属性不单是指针,他们同样包含在指向面中定点的索引,和vcg::face::FFAdj同样的效果。如上图展示了实际的例子,与Face-Face adjacent相似,需要使用vcg::tri::UpdateTopology::VertexFace(MeshType& m)来初始化。
Vertex的VF邻接关系
v.VFp() == f2 顶点的VFp是一个指针,指向此定点关联的面的列表的第一个面。
v.VFi() == 0 定点的VFi是一个索引值,是所指向的面中的定点所在的序号
face的VF邻接关系,即,面中的指定索引值i顶点,其所对应的邻接面的序列的首个面的指针
f2->VFp() == f3 ,即f2面中的0索引定点,其所对应的临界面的序列的首个面的指针,即面f3
f2->VFi() == 1 ,即f2面中的0索引点,其再所对应的邻接面的首个面中的相应的该(本身)定点所在的序号。
f3->VFp() == f1
f3->VFi() ==
f1->VFp() == f0
f1->VFi() ==
f0->VFp() == NULL
f0->VFi() == -
VFIterator
VFIterator是一个简单的迭代器,来遍历一个顶点的所有邻接三角形面,通过使用VFAdjacency属性。其用法如下图:
sf/apps/sample/trimesh_pos_demo/trimesh_vfiter_demo.cpp
#include <vcg/simplex/face/pos.h> // include the definition of VFIterator
//...includes to define your mesh type
class MyVertex: public vcg::VertexSimp2<MyVertex,MyEdge,MyFace, vcg::vertex::VFAdj /*,... other attributes*/ >{};
class MyFace: public vcg::FaceSimp2<MyVertex,MyEdge,MyFace, vcg::face::VertexRef,vcg::face::VFAd>{};
void OneRingNeighborhoodVF( MyVertex * v)
{
vcg::face::VFIterator<MyFace> vfi(v); //initialize the iterator tohe first face
for(;!vfi.End();++vfi)
{
MyFace* f = vfi.F();
// ...do something with face f
}
}
Stars and Rings
端点顶点的face和vertices集合,可以使用以下方式函数:
- vcg::face::VFOrderedStarFF
- vcg::face::VVStarVF
- vcg::face::VFStarVF
- vcg::face::VFExtendedStarVF
- vcg::face::EFStarFF
面面邻接与点面邻接中的少量的面的处理
以下陈述可以避免“冲突”,来帮助选择最适合的临街对象
endl;
几个经典的数学库之一学习---VCGlib(1)的更多相关文章
- 几个经典的数学库之一学习---VCGlib(2)
几个经典的数学库之一学习---VCGlib(2) 1. Optional Component(可选的组件) 有许多Vertex和Face的属性并不是一直都是必要的,如Face-Face的邻接关系.VC ...
- 几个经典的数学库之一学习---VCGlib(3)
Camera and shot abstraction for managing views 视图的定义,以及mesh的操作说明. Shot(镜头) and camera(相机) shot摄像结构以及 ...
- DirectX11 学习笔记6 - 使用D3DXMATH数学库的一个样例
这个样例是在之前的样例基础上 .把之前d3dx10math数学库换成了最新的d3dxmath.长处就不说了.先上效果图 所有代码.以及效果文件 文件结构 所有代码: 依照上图的文件顺序 #pragma ...
- <泛> C++3D数学库设计详解 向量篇
// 注:本内容为作者原创,禁止在其他网站复述内容以及用于商业盈利,如需引用,请标明出处:http://www.cnblogs.com/lv_anchoret/ Preface 为了支持光线追踪的学习 ...
- GEOS库的学习之一:介绍和编译
对GEOS库的学习,源于一个项目:要在c++中判断二维平面中两个多边形的关系(无论凹凸).也就是判断两个多边形是否相交.相容等.听起来很简单,可实现起来却比较难,而项目又催得紧.于是我去搜索了一下,看 ...
- 标准模板库(STL)学习探究之stack
标准模板库(STL)学习探究之stack queue priority_queue list map/multimap dequeue string
- 标准模板库(STL)学习探究之vector容器
标准模板库(STL)学习探究之vector容器 C++ Vectors vector是C++标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库.vector之所以被 ...
- 微软数学库XNAMATH(DirectXMath)
这篇文章只是对着MSDN文档的一些吐槽和总结记录,个人笔记之类的 运行库与头文件 老实说,这个数学库微软还是更像蛮频繁的,我这里有的最早版本是伴随DX9的,在这个头文件里面 最近在使用DXUT,顺便也 ...
- 一个很cool的C#的高性能数学库
High Performance Math Library for C# and .NET是一个很cool的C#的高性能数学库,3D效果也很不错,下图是首页上的一个例子.他也有一个交互的网页,你可以自 ...
随机推荐
- 疯狂JAVA——第八章 java集合
集合类主要负责保存.盛装其他数据,因此集合类也被称为容器类. 数组元素既可以是基本类型的值,也可以是对象(实际上是保存的对象的引用): 集合里只能保存对象.
- frm和ibd恢复sql文件的操作
情况:有mysql中data文件(仅仅一个数据库) 操作:frm和ibd恢复sql文件的操作 1.创建相同名字的库xxx 2.把ibdata1替换成原来的 3.把数据库xxx内内容全部替换为原来的 完 ...
- 求2的n次方对1e9+7的模,n大约为10的100000次方(费马小定理)
昨天做了一个题,简化题意后就是求2的n次方对1e9+7的模,其中1<=n<=10100000.这个就算用快速幂加大数也会超时,查了之后才知道这类题是对费马小定理的考察. 费马小定理:假如p ...
- clion register
1. 使用 activation code 激活 安装完软件后,启动,在要求输入注册码的界面(菜单栏 ⇒ help ⇒ register)选择“License server”输入“http://ide ...
- forward(请求转发)和redirect(重定向)的区别
原理: forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器,浏览器根本不知道服务器发送的内容是从哪儿来的,所以它的地址栏中还是原 ...
- 动态调用WebService方法
好像很多人做WebService的时候都是直接添加引用的方式,然后调用服务端的方法.这样就个问题,就是每次我服务端添加了方法或者修改了方法后都要更新Web引用,这样比较麻烦.下面给一个不用添加引用 ...
- [leetcode]392. Is Subsequence 验证子序列
Given a string s and a string t, check if s is subsequence of t. You may assume that there is only l ...
- linux文件管理2
1.显示文件内容 cat : 显示文件内容 tac : 倒序显示内容 2.更改文件权限 chmod :更改文件权限 -R 递归改变 chown :更改文件拥有者 -R 递归改变 chgrp :更改文件 ...
- JFinal架构简介
JFinal 是基于Java 语言的极速 web 开发框架,其核心设计目标是开发迅速.代码量少.学习简单.功能强大.轻量级.易扩展.Restful.在拥有Java语言所有优势的同时再拥有ruby.py ...
- Python打杂之路
1.任务要落到纸上好记性不如烂笔头,再好的记性也不如写到纸上明确无误,写到纸上就不用担心会漏掉哪项工作.平时,我们总是在忙着一项工作的同时还惦记着下一项工作,把工作都记下后,我们就可以专注于一项工作, ...