vcg面面关系

vcg面面关系

vcg的面面关系通过tri::UpdateTopology::FaceFace方法初始化

FaceFace

1.先获取所有的边

static void FillEdgeVector(MeshType &m, std::vector &e, bool includeFauxEdge=true)
。。。
//先遍历面获取边的数量
for(fi = m.face.begin(); fi != m.face.end(); ++fi) if(! (*fi).IsD()) n_edges+=(*fi).VN();//遍历所有的面获取边信息
(*p).Set(&(*pf),j) //pf为面  j代表第几个顶点(边)//对所有的边进行排序,排序的依据取决于 inline bool operator <  ( const PEdge & pe ) const
//先比较第一个点的地址,然后比较第二个,由于顶点是存储在vector中,所以地址是连续的//根据边信息获取面信息//重第一条边开始typename std::vector::iterator pe,ps;ps = e.begin();pe=e.begin();//循环分析关系do{//判断是否已到结尾或者边是否相等(两个顶点相同)if( pe==e.end() || !(*pe == *ps) )          {typename std::vector::iterator q,q_next;//遍历重开始到迭代器结尾迭代器前一个迭代器的所有边for (q=ps;q1;++q)                     {//边序号必须大于-1assert((*q).z>=0);//获取相对于当前迭代器的下一个迭代器q_next = q;++q_next;//确保下一个迭代器边序号大于-1assert((*q_next).z>=0);//确保下一个迭代器变序号小于面的顶点数assert((*q_next).z< (*q_next).f->VN());//FFp函数:(*this).Base().AF[(*this).Index()]._fp[j]//(*this).Index()表示当前面的序号,也就是(*q).f这个面的序号//AF为std::vector AV//整句代码表示(*q).f这个面的第q->z条边的邻接面为(*q_next).f(*q).f->FFp(q->z) = (*q_next).f;    //类似的,(*q).f这个面的第q->z个点(边)是(*q_next).f这个面的第z个点(边)           (*q).f->FFi(q->z) = (*q_next).z;}assert((*q).z>=0);assert((*q).z< (*q).f->VN());//回过头来处理q_next的信息(*q).f->FFp((*q).z) = ps->f;(*q).f->FFi((*q).z) = ps->z;//下个循环从pe开始ps = pe;++ne;                                     }//结尾的迭代器已到结尾那么分析结束if(pe==e.end()) break;//否则结尾迭代器往前进一位++pe;} while(true);

分析边的几种情况
1.ps边没有是边界边,也就是没有多个三角形共用这条边,这种情况下pe为ps+1,也就是说for (q=ps;q 循环无法进入,但是for循环下面的代码会执行,也就是

(*q).f->FFp((*q).z) = ps->f;
(*q).f->FFi((*q).z) = ps->z;
此时q==ps,所以边界边的邻接三角形就是自己

2.ps边为两个三角形共用的边,这是比较常规的情况,此时pe=pe+1,由于边数据是排过序的,所以此时pe=ps,那么++pe,接着进行下一次判断,此时q_next就是pe+1,由于pe与q_next是同一条边当时属于两个三角形,所以三角形的邻接关系就出来了,处理完两条边相互之间的邻接关系之后,ps=pe,++pe,开始下一轮循环

3.ps边为超过两个三角形共用的边,也就是交叠边现象,此时pe会多次++跳过这些三角形,for循环中会依次处理这些交叠的三角形,但是否循环之后,只会处理最后一个三角形与倒数第一个三角形关于这条边的邻接关系:
比如 f1 f2 f3是这种交叠的关系,
那么f1对于交叠边的邻接三角形是f2
f2对于交叠边的邻接三角形是f3
f3对于交叠边的临界三角形是f1

情况二是情况三的一种特殊情况

tri::Clean::CountNonManifoldEdgeFF

获取交叠边的数量
主要方法为

//如果是流形边,返回true,否则返回false
template <class FaceType>
inline bool IsManifold( FaceType const & f, const int j )
{//确保面面关系不为空,也就是经过了FaceFace函数assert(f.cFFp(j) != 0); // never try to use this on uncomputed topologyif(FaceType::HasFFAdjacency())//f.cFFp(j) == &f代表边界边//f.cFFp(j)->cFFp(f.cFFi(j)) f第j条边的邻接面的对应边的邻接面f1,如果f==f1,说明是正常的邻  //接关系return ( f.cFFp(j) == &f || &f == f.cFFp(j)->cFFp(f.cFFi(j)) );elsereturn true;
}


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部