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);
}
这么写感觉怪怪的但是能运行过这一段

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