Recently I am implementing the QEM mesh simplification algorithm, which was originally from Michael Garland and Paul S. Heckbert's paper Surface Simplification Using Quadric Error Metrics.
According to the algorithm, we should compute a contraction cost
for each edge, and put all the edges into a minimal heap, so that every time we pick up an edge with the minimal cost to contract. However, the contraction may cause the incident triangles fold over, i.e. the norm changes over 90 degrees before and after the contraction. The fold-over phenomenon can be visualized by the following example:
Suppose the edge with the minimal cost we pick up is V1V2
, and we are about to contract it. We foresee the contraction will cause V1
and V2
merge together as the figure shows. More importantly, if we define the norm of the triangle Tri(ABV2)
as cross_product(V2A, V2B)
, we can find this norm changes its direction from pointing outwards to inwards. This is not what we want. The paper says if encounter this situation, we should "penalize" this operation, i.e. adding a large number to V1V2
's cost so that V1V2
becomes non-top of the heap, which means it will not be picked up at this moment. Instead, we will pick up the next edge with the minimal cost.
The algorithm can be written with the following pseudo code:
while (number_of_left_edges > Pre_defined_number)
{
Edge e = EdgeHeap.top();
if (Check_edge_will_cause_foldover(e))
{
e.cost += A_VERY_LARGE_NUMBER;
EdgeHeap.update();
}
else
{
e.Contract();
Do_something_on_incident_triangles(e.Triangles);
EdgeHeap.pop();
}
}
However, I found a very tough problem. As mentioned, when I found the contraction of an edge E1
may cause fold-over of some triangles, I enlarged its cost and threw it back to the heap, then I picked another edge E2
, and still found it would cause fold-over. So and so forth. I didn't find an edge could be contracted any more, so that the loop infinitely continued, and actually no edge be simplified.
Is there any one who can give me any hint about the algorithm, so that to solve the problem? Thank you so much!