1、常见的Mesh增加点和增加面的方法如下:
#include<vcg/complex/allocate.h>
#include<vector>
typedef vcg::MyMesh CMeshO; //mesh类型
typedef vcg::Point3f Point3;//顶点类型
typedef vcg::Point3i Tri; //三角形结构
//向m中增加新的三角形
void add(CMeshO &m, std::vector<Point3> addPnts, std::vector<Tri> addTris)
{
for (int j = 0, jsize = addPnts.size(); j < jsize; ++j)
{
vcg::tri::Allocator<CMeshO>::AddVertex(m, addPnts[j]);
}
for (int j = 0, jsize = addTris.size(); j < jsize; ++j)
{
vcg::tri::Allocator<CMeshO>::AddFace(m, addTris[j][0], addTris[j][1], addTris[j][2]);
}
}
以AddVertex为例,我们进一步阅读源代码,可知:
(1)最终实现为:vcg\complex\allocate.h中 static VertexIterator AddVertices(MeshType &m, size_t n, PointerUpdater<VertexPointer> &pu)
在如图所示位置:
首先,resize了 vert数组的大小,既在末尾新增了一个空间,其次让vn增加。你以为这样结束了吗?其实并没有,他还做了后续操作接着往下看,该到 PointerUpdater<VertexPointer>的作用了。
(2)在前后进行resize的时候分别对vert的坐标索引进行了记录,如果前后不一致,意味着m中的face数组需要进行修改,原因是:face中记录的是vertex的地址,resize之后vertex的地址发生了改变。
(3)接下来我们进一步解析,Update函数
经过上述分析,你应该明白了 addVertex函数每次增加一个点所进行的操作了吧,那么for这样的操作是否经得起推敲呢?
2、进阶版的增加三角形
#include<vcg/complex/allocate.h>
#include<vector>
typedef vcg::MyVertex CVertexO;//顶点结构
typedef vcg::MyFace CFaceO; //面结构
typedef vcg::MyMesh CMeshO; //mesh类型
typedef vcg::Point3f Point3; //顶点类型
typedef vcg::Point3i Tri; //三角形顶点索引
//向m中增加新的三角形
void add(CMeshO &m, std::vector<Point3> addPnts, std::vector<Tri> addTris)
{
CVertexO * oldBase = &m.vert[0];//原坐标首地址
int oldvSize = m.vert.size();//原顶点数量
m.vert.resize(oldvSize + addPnts.size());//增加点
m.vn = oldvSize + addPnts.size();//更新顶点数量
for (int j = oldvSize; j < m.vn; ++j)
{
m.vert[j].P() = addPnts[j- oldvSize];//新增点赋值
}
int oldtSize = m.face.size();//原三角形数量
m.face.resize(oldtSize + addTris.size());
for (int j = 0, jsize = addTris.size(); j < jsize; ++j)
{
for (int i = 0; i < 3; ++i)
m.face[oldtSize + j].V(i) = &m.vert[addTris[j][i]];
}
//更新旧的三角形
for (int j = 0; j < oldtSize; ++j)
{
CFaceO &f = m.face[j];
for (int i = 0; i < 3; ++i)
m.face[oldtSize + j].V(i) = &m.vert[f.V(i)- oldBase];
}
//更新三角形数量
m.fn += addTris.size();
}