20230831更新:更正了原示例代码中几处小错误。
前言
本文是对vcg
库自带的示例进行学习,从而达到熟练使用该库的目的。
网格结构定义
使用vcglib
定义网格结构非常简单,如果不考虑深入研究其内部实现的话。代码如下:
//mymesh.h
#include<vcg/complex/complex.h>
class myFace;
class myVertex;
class myUsedTypes:public vcg::UsedTypes<vcg::Use<myVertex>::AsVertexType,vcg::Use<myFace>::AsFaceType>{};
class myVertex:public vcg::Vertex<myUsedTypes,vcg::vertex::Coord3f,vcg::vertex::Normal3f,vcg::vertex::Color4b,vcg::vertex::BitFlags>{};
class myFace:public vcg::Face<myUsedTypes,vcg::face::VertexRef,vcg::face::Normal3f,vcg::face::FFAdj,vcg::face::BitFlags>{};
class myMesh:public vcg::tri::TriMesh<std::vector<myVertex>,std::vector<myFace>>{};
上述代码中,首先前置声明两个类:myFace
和myVertex
,然后定义myUsedTypes
类,该类继承了vcg
库的UsedTypes
类,顾名思义,说明自定义的网格结构中使用myFace
作为面片类型,使用myVertex
作为顶点类型。myVertex
类继承vcg
的顶点类,具有坐标、法线和颜色属性,以及一个32位的比特数组标志(跟踪添加、删除、访问等操作);myFace
类继承vcg
的面片类,具有:面片顶点的引用(三个指向顶点类型的指针)、面片法线、指示面之间的邻接关系以及二进制标志。
面之间的邻接关系解释:该属性通过边编码面片之间的邻接性。对于二维流形的边(每条边只被两个面片共享)来说,它仅仅指向当前面片对应的另一个面片;对于非二维流形的边来说,它保存一个指向下一个面片的指针(边界边指向自身)。
最后定义的myMesh
类继承了vcg::tri::TriMesh
,实际上是该库内部对于三角网格的实现,使用自定义的顶点数组和面片数组作为参数。
使用坐标和索引创建模型
#include<iostream>
#include<vector>
#include<vcg/complex/algorihhms/create/platonic>
#include<wrap/io_trimesh/export_off.h>
#include<wrap/io_trimesh/export_obj.h>
#include"mymesh.h"
int main(int argc, char*argv[])
{
using masepace std;
//使用坐标和索引创建网格模型,并保存称off格式
vector<vcg::Point3f>coords;
vector<vcg::Point3i>index;
coords.push_back(vcg::Point3f(0,0,0));
for(int i=0;i<36;++i)
{
float angleRad=float(i)*M_PI/18.0;
coords.push_back(vcg::Point3f(sin(angleRad),cos(angleRad),0));
index.push_back(vcg::Point3i(0,i+1,1+(i+1)%36));
}
myMesh m1;
vcg::tri::BuildMeshFromCoordVectorIndexVector(m1,coords,index);
vcg::tri::io::ExporterOFF<MyMesh>::Save(m1,"disc.off")
//使用vcg库内部提供的模型,并保存称obj格式
myMesh m2;
vcg::tri::Octahedron(m2);
vcg::tri::io::ExporterOBJ<MyMesh>::Save(m2,"octahedron.obj",0);
return 0;
}
貌似vcg
官网中的示例都是保存为off
格式,同样的Save()
函数,保存为obj
格式需要三个参数,查看了源码:
static int Save(SaveMeshType &m, const char * filename, int mask=0 ); //以off格式输出
static int Save(SaveMeshType &m, const char * filename, int mask, CallBackPos *cb = 0); //以obj格式输出
只是因为前者的mask
参数提供了默认参数值而已,该参数可用于控制输出的属性内容,值为0表示默认输出顶点和面片索引。
保存文件内容分别为:
结果展示
上图左边m1
的输出,右边是m2
的输出。