实验 2.7 坍缩时遍历点出现问题

在进行坍缩时,我的想法是保留 v1 并调整位置,删除 v2(v1v2 为给定边的两个点),因此需要遍历 v2 所有的指出的半边,并将其 from 信息改为 v1,代码逻辑为:

    Halfedge* temp_h = v2->halfedge;
    do {
        temp_h->from = v1;
        temp_h = temp_h->inv->next;

        logger->warn("id: {}", temp_h->id);
        logger->warn("##########id: {}", v2->halfedge->id);

    } while (temp_h != v2->halfedge);

而在运行时,对于 teapot 这个模型来说(cow 模型有同样的问题),杯身部分的横向边,斜边能够正常坍缩,但是对于竖边,遍历时会出现问题,遍历顺序见下图(通过打印 halfedge 的 id 与界面显示 id 对照确认),这样就导致死循环,请问为什么会出现这种现象?

(坍缩了右侧一条斜边与一条横边的结果)

(试图坍缩竖边时的错误遍历顺序,图中 0 为 v2 的 halfedge,而 12345678 为陷入死循环后的遍历顺序)

可以看出问题在于遍历到 3 号边(id7499)时,下一条正常应为(id 7504),而却变为了(id 7508)。当我在程序中手动进行(id 7499)->inv->next 时,得到(id 7504)

你的思路本身应该是没有问题的,所以我估计代码的问题并不在你贴上来的部分中。

从这张图

和你标出的编号中可以看到:陷入死循环时遍历半边的顺序,与正确坍缩完成后遍历 v_1 顶点发出半边的顺序相同,即 1 号到 7 号这些半边好像都已经被连接到了 v_1 顶点上一样,而 v_2 发出的第一条半边(0 号)好像已经不存在了

因此我猜测:你在进入循环修改半边的 from 之前应该还做了别的事情,包括删除被坍缩的边和它所在的两个面,并且已经修改了被影响半边的 invnext 关系。这样才会导致修改 from 时,遍历半边的结果与期望的不同。而在 GUI 界面上手动操作时还没有进行坍缩,所以此时的邻接关系是正确的。

请始终注意,局部操作修改各种基本元素的过程中,半边网格处于中间的非法状态,所以必须谨慎考虑修改各种链接铦袭的顺序,以免相互影响导致出错。如果我猜得没问题,你可以在下面两种改法中选择一种:

  • 把修改 from 关系的循环移到修改 invnext 之前。
  • 在一开始就遍历 v_2 发出的半边,但不要立刻修改,而是先存储到一个 vector<Halfedge*> 里,之后遍历这个 vector 进行修改。
1 Like