Refactor: improve (still unused) UV unwrap simplify code

Use vector instead of malloc, make cost function a callback, tweak names
and comments for clarity.
This commit is contained in:
Brecht Van Lommel 2023-11-24 18:21:46 +01:00
parent c1f931a399
commit 0da822e471
1 changed files with 37 additions and 27 deletions

View File

@ -1384,11 +1384,13 @@ static void p_polygon_kernel_center(float (*points)[2], int npoints, float *cent
} }
#endif #endif
#if 0 /* Simplify/Complexity
/* Edge Collapser */ *
* This is currently used for elminating degenerate vertex coordinates.
* In the future this can be used for efficient unwrapping of high resolution
* charts at lower resolution. */
int NCOLLAPSE = 1; #if 0
int NCOLLAPSEX = 0;
static float p_vert_cotan(const float v1[3], const float v2[3], const float v3[3]) static float p_vert_cotan(const float v1[3], const float v2[3], const float v3[3])
{ {
@ -1941,7 +1943,12 @@ static float p_collapse_cost(PEdge *edge, PEdge *pair)
return cost; return cost;
} }
static void p_collapse_cost_vertex(PVert *vert, float *r_mincost, PEdge **r_mine) static void p_collapse_cost_vertex(
PVert *vert,
float *r_mincost,
PEdge **r_mine,
const std::function<float(PEdge *, PEdge *)> &collapse_cost_fn,
const std::function<float(PEdge *, PEdge *)> &collapse_allowed_fn)
{ {
PEdge *e, *enext, *pair; PEdge *e, *enext, *pair;
@ -1949,8 +1956,8 @@ static void p_collapse_cost_vertex(PVert *vert, float *r_mincost, PEdge **r_mine
*r_mincost = 0.0f; *r_mincost = 0.0f;
e = vert->edge; e = vert->edge;
do { do {
if (p_collapse_allowed(e, e->pair)) { if (collapse_allowed_fn(e, e->pair)) {
float cost = p_collapse_cost(e, e->pair); float cost = collapse_cost_fn(e, e->pair);
if ((*r_mine == nullptr) || (cost < *r_mincost)) { if ((*r_mine == nullptr) || (cost < *r_mincost)) {
*r_mincost = cost; *r_mincost = cost;
@ -1964,8 +1971,8 @@ static void p_collapse_cost_vertex(PVert *vert, float *r_mincost, PEdge **r_mine
/* The other boundary edge, where we only have the pair half-edge. */ /* The other boundary edge, where we only have the pair half-edge. */
pair = e->next->next; pair = e->next->next;
if (p_collapse_allowed(nullptr, pair)) { if (collapse_allowed_fn(nullptr, pair)) {
float cost = p_collapse_cost(nullptr, pair); float cost = collapse_cost_fn(nullptr, pair);
if ((*r_mine == nullptr) || (cost < *r_mincost)) { if ((*r_mine == nullptr) || (cost < *r_mincost)) {
*r_mincost = cost; *r_mincost = cost;
@ -2050,9 +2057,12 @@ static void p_chart_post_collapse_flush(PChart *chart, PEdge *collapsed)
} }
} }
static void p_chart_post_split_flush(PChart *chart) static void p_chart_simplify_compute(PChart *chart,
std::function<float(PEdge *, PEdge *)> collapse_cost_fn,
std::function<float(PEdge *, PEdge *)> collapse_allowed_fn)
{ {
/* Move from `collapsed_*`. */ /* For debugging. */
static const int MAX_SIMPLIFY = INT_MAX;
PVert *v, *nextv = nullptr; PVert *v, *nextv = nullptr;
PEdge *e, *nexte = nullptr; PEdge *e, *nexte = nullptr;
@ -2092,18 +2102,18 @@ static void p_chart_simplify_compute(PChart *chart)
* is at the top of the respective lists. */ * is at the top of the respective lists. */
Heap *heap = BLI_heap_new(); Heap *heap = BLI_heap_new();
PVert *v, **wheelverts; PVert *v;
PEdge *collapsededges = nullptr, *e; PEdge *collapsededges = nullptr, *e;
int nwheelverts, i, ncollapsed = 0; int ncollapsed = 0;
Vector<PVert *> wheelverts;
wheelverts = MEM_mallocN(sizeof(PVert *) * chart->nverts, "PChartWheelVerts"); wheelverts.reserve(16);
/* insert all potential collapses into heap */ /* insert all potential collapses into heap */
for (v = chart->verts; v; v = v->nextlink) { for (v = chart->verts; v; v = v->nextlink) {
float cost; float cost;
PEdge *e = nullptr; PEdge *e = nullptr;
p_collapse_cost_vertex(v, &cost, &e); p_collapse_cost_vertex(v, &cost, &e, collapse_cost_fn, collapse_allowed_fn);
if (e) { if (e) {
v->u.heaplink = BLI_heap_insert(heap, cost, e); v->u.heaplink = BLI_heap_insert(heap, cost, e);
@ -2119,7 +2129,7 @@ static void p_chart_simplify_compute(PChart *chart)
/* pop edge collapse out of heap one by one */ /* pop edge collapse out of heap one by one */
while (!BLI_heap_is_empty(heap)) { while (!BLI_heap_is_empty(heap)) {
if (ncollapsed == NCOLLAPSE) { if (ncollapsed == MAX_SIMPLIFY) {
break; break;
} }
@ -2145,15 +2155,15 @@ static void p_chart_simplify_compute(PChart *chart)
p_collapsing_verts(edge, pair, &oldv, &keepv); p_collapsing_verts(edge, pair, &oldv, &keepv);
/* gather all wheel verts and remember them before collapse */ /* gather all wheel verts and remember them before collapse */
nwheelverts = 0; wheelverts.clear();
wheele = oldv->edge; wheele = oldv->edge;
do { do {
wheelverts[nwheelverts++] = wheele->next->vert; wheelverts.append(wheele->next->vert);
nexte = p_wheel_edge_next(wheele); nexte = p_wheel_edge_next(wheele);
if (nexte == nullptr) { if (nexte == nullptr) {
wheelverts[nwheelverts++] = wheele->next->next->vert; wheelverts.append(wheele->next->next->vert);
} }
wheele = nexte; wheele = nexte;
@ -2162,18 +2172,16 @@ static void p_chart_simplify_compute(PChart *chart)
/* collapse */ /* collapse */
p_collapse_edge(edge, pair); p_collapse_edge(edge, pair);
for (i = 0; i < nwheelverts; i++) { for (PVert *v : wheelverts) {
float cost; float cost;
PEdge *collapse = nullptr; PEdge *collapse = nullptr;
v = wheelverts[i];
if (v->u.heaplink) { if (v->u.heaplink) {
BLI_heap_remove(heap, v->u.heaplink); BLI_heap_remove(heap, v->u.heaplink);
v->u.heaplink = nullptr; v->u.heaplink = nullptr;
} }
p_collapse_cost_vertex(v, &cost, &collapse); p_collapse_cost_vertex(v, &cost, &collapse, collapse_cost_fn, collapse_allowed_fn);
if (collapse) { if (collapse) {
v->u.heaplink = BLI_heap_insert(heap, cost, collapse); v->u.heaplink = BLI_heap_insert(heap, cost, collapse);
@ -2183,7 +2191,6 @@ static void p_chart_simplify_compute(PChart *chart)
ncollapsed++; ncollapsed++;
} }
MEM_freeN(wheelverts);
BLI_heap_free(heap, nullptr); BLI_heap_free(heap, nullptr);
p_chart_post_collapse_flush(chart, collapsededges); p_chart_post_collapse_flush(chart, collapsededges);
@ -2191,6 +2198,9 @@ static void p_chart_simplify_compute(PChart *chart)
static void p_chart_complexify(PChart *chart) static void p_chart_complexify(PChart *chart)
{ {
/* For debugging. */
static const int MAX_COMPLEXIFY = INT_MAX;
PEdge *e, *pair, *edge; PEdge *e, *pair, *edge;
PVert *newv, *keepv; PVert *newv, *keepv;
int x = 0; int x = 0;
@ -2210,7 +2220,7 @@ static void p_chart_complexify(PChart *chart)
p_split_vertex(edge, pair); p_split_vertex(edge, pair);
p_collapsing_verts(edge, pair, &newv, &keepv); p_collapsing_verts(edge, pair, &newv, &keepv);
if (x >= NCOLLAPSEX) { if (x >= MAX_COMPLEXIFY) {
newv->uv[0] = keepv->uv[0]; newv->uv[0] = keepv->uv[0];
newv->uv[1] = keepv->uv[1]; newv->uv[1] = keepv->uv[1];
} }
@ -2971,7 +2981,7 @@ static void p_chart_lscm_begin(PChart *chart, bool live, bool abf)
return; return;
} }
#if 0 #if 0
p_chart_simplify_compute(chart); p_chart_simplify_compute(chart, p_collapse_cost, p_collapse_allowed);
p_chart_topological_sanity_check(chart); p_chart_topological_sanity_check(chart);
#endif #endif