vcg面面关系

vcg面面关系

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

FaceFace

1.先获取所有的边

static void FillEdgeVector(MeshType &m, std::vector<PEdge> &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<PEdge>::iterator pe,ps;
  ps = e.begin();pe=e.begin();
  //循环分析关系
  do
  {
    //判断是否已到结尾或者边是否相等(两个顶点相同)
    if( pe==e.end() || !(*pe == *ps) )          
    {
      typename std::vector<PEdge>::iterator q,q_next;
      //遍历重开始到迭代器结尾迭代器前一个迭代器的所有边
      for (q=ps;q<pe-1;++q)                     
      {
        //边序号必须大于-1
        assert((*q).z>=0);
        //获取相对于当前迭代器的下一个迭代器
        q_next = q;
        ++q_next;
        //确保下一个迭代器边序号大于-1
        assert((*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<struct AdjTypePack> 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<pe-1;++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<CMeshO>::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 topology
  if(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)) );
  else
    return true;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值