2.10 各向同性重网络化

我在 2.10 各向同性重网络化坍缩某些边的时候遇到了卡死的问题,这个问题比较奇怪,有些边可以坍缩成功,另一些边就会卡死。
我的思路是先把要坍缩和分裂的边放到 set 里面,而且我也考虑了如果坍缩后临边大于 4/3 L 的情况,不大于才放进 set 中,

printf("Sucsess1\n");
        // Process selected edges: split or collapse them
        for (Edge* e : selected_edges)
        {
            if (e->length() < EdgeMeanLength * 4.0f / 5.0f)
            {
                printf("Attempting to collapse edge: %zu\n", e->id);
                collapse_edge(e);
                printf("Collapse successful: %zu\n", e->id);
            }
            else if (e->length() > EdgeMeanLength * 4.0f / 3.0f)
            {
                split_edge(e);
                printf("Sucsess split\n");
            }
        }
        printf("Sucsess2\n");

但是我执行操作的时候前面坍缩都很好,但是到了某条边就直接卡住了,是在判断坍缩安全性的时候。

int coVertex = 0;//共同顶点的个数
    Halfedge* hm = v1->halfedge;
        do
        {
            Halfedge* hn = v2->halfedge;
            do
            {
                if(hm->inv->from == hn->inv->from)
                {
                    coVertex++;
                }
                hn = hn->inv->next;
            } while (hn != v2->halfedge);
            hm = hm->inv->next;
        } while (hm != v1->halfedge);
    printf("success 1\n");
    if(coVertex == 2)
    {

虽然笨,但是感觉这个双循环也是一种求共同顶点的办法。

他会卡死在内层循环,其中 printf 用来调试。我曾尝试打印半边的地址,发现他们一直循环,这样的话他应该会在 hn != v2->halfedge 跳出循环才对,但是没有这么做。有点不理解为什么有的边就可以坍缩成功,有的就不行并卡死在寻找共同顶点的 do while 循环中。
或者说,还有更好的寻找共同顶点的办法?
这个 12582 边不是边界边

这处死循环可能是因为你在尝试 collapse 一条已经被 erase 过的边,因为我遇到过。
具体来说,在你的代码中,一次 collapse_edge(e) 会 erase 包括 e 在内总计 3 条 edge,那如果除了 e 之外,另外两条边也在 selected_edge 里的话,就会出现这个错误。
此外,这种错误靠 validate() 检查不出来,因为它本身已经不在网格里了。

for(Edge* e = edges.head; e != nullptr; e = e->next_node)
        {
            Halfedge* h = e->halfedge;
            Vertex* v1 = h->from;
            Vertex* v2 = h->inv->from;
            Vertex* v3 = h->prev->from;
            Vertex* v4 = h->inv->prev->from;
            size_t d_Per = std::abs(static_cast<long>(v1->degree()-6)) + std::abs(static_cast<long>(v2->degree()-6)) + 
                           std::abs(static_cast<long>(v3->degree()-6)) + std::abs(static_cast<long>(v4->degree()-6));
            size_t d_Aft = std::abs(static_cast<long>(v1->degree()-7)) + std::abs(static_cast<long>(v2->degree()-5)) + 
                           std::abs(static_cast<long>(v3->degree()-7)) + std::abs(static_cast<long>(v4->degree()-5));
            if(d_Per > d_Aft)
            {
                flip_edge(e);
                printf("Flip successful: %zu\n", e->id);
            }
        }

这是我的边翻转的操作,为什么我翻转边也会卡死,没有理解,我前面的做法是定义了两个 set 类,分别存放要坍缩和分裂的,考虑到一次坍缩少三条边,我坍缩这么来写的:

for(Edge* e : selectedCollapseEdges)
        {
                printf("Attempting to collapse edge: %zu\n", e->id);
                if(selectedCollapseEdges.find(e->halfedge->next->edge) != selectedCollapseEdges.end())
                {
                    selectedCollapseEdges.erase(e->halfedge->next->edge);
                }
                if(selectedCollapseEdges.find(e->halfedge->inv->next->edge) != selectedCollapseEdges.end())
                {
                    selectedCollapseEdges.erase(e->halfedge->inv->next->edge);
                }                
                    collapse_edge(e);
                    
                printf("Collapse successful: %zu\n", e->id);
        }

这么写感觉怪怪的但是能运行过这一段


这个是我翻转卡死的终端,我不知道是什么原因。 :weary: :tired_face: :weary: :tired_face: