三维重建——孔洞填补算法

本文介绍了如何使用openMesh库进行三维重建的孔洞填补。通过找到孔洞、排序半边、计算角度和距离,逐步构建新的三角面片。针对不同情况,如两点间距离过长,采取插入点的方式进行填补。提供了关键代码示例,并指出算法仍有优化空间。
摘要由CSDN通过智能技术生成

本文是借助openMesh库进行三维重建的孔洞填补的。openMesh里面有非常优秀的三维的数据结构。

核心:

找到三维模型当中所有的空洞,对于每一个孔洞,找出其所有的半边然后对其进行排序;对排序过的所有的半边,找到角度最小的两条边,增加第三条边,形成新的三角面片;如此迭代。具体的每一步的算法如下:

  1. 半边排序算法:
    对于一个孔洞,找出其中的一条半边作为起始边,遍历所有其他的半边集合,找到以该条半边的尾点作为起点的半边;如此迭代,直到找到某一条边的尾点是第一条边的起点为止。

  2. 计算角度:
    不同的两种孔洞
    对于上面这两种孔洞,箭头处可能角度都比较的小,但是图2 当中就是不能填补的。因此,计算的角度是和他们的方向是有关的。
    计算的方法是:首先求出这个角度的大小(利用向量求出来一个0~180度之间的一个值angle,然后再确定由这两条边组成的一个面的法向量是否和第一条边对面的边所在的面的法向量一致,一致则输出角度,不一致则输出: 360-angle;

  3. 计算距离:

    两点的欧拉距离计算公式;

  4. 单个孔洞填补算法:
    如下图所示:
    两种填补的方式
    如果 两点之间的距离过长(图3),则考虑在中间插入一个点(实际上是替换点),增加两个三角面片,用最外侧的两个半边句柄更新整个半边句柄;否则直接增加一个三角面片,更新句柄(图4)。

关键代码:

// 找到一个洞的半边集合, 排序
void DFS(int nNum, int n)// 在这n条半边当中找到并排序到  有序边对列的第 nNum 条处。   但这个只能是对一个孔洞
{
    if (toTemp[nNum - 1] == fromTemp[0])// 首尾相接的意思吧,就是说找到最后一个了。 也就是完成了所有的边的排序
    {
        if (nNum < vNum)
        {
            vNum = nNum;//原来分配的空间大了, 这是这个环里面的边的条数, ******** 而n表示的是总的半边的数目

            for (int i = 0; i < vNum;++i )
            {
                fromV[i] = fromTemp[i];//  直到找到了所有的半边后,才将所有的半边放入有序的半边集合,这样节省空间
                toV[i] = toTemp[i];
            }
        }
        return;
    }
    for (int i = 1; i < n;i ++)// n是给定的值,半边的个数
    {
        if (!vis[i] && toTemp[nNum - 1] == fromVetex[i])// 找到没有存储的且以 上一个尾点 为 起点的边
        {
            fromTemp[nNum] = fromVetex[i];
            toTemp[nNum] = toVetex[i];
        
评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值