Fix #105058: fix UV ABF++ bounds check on large angles

Previous code had a faulty do-while-loop which only checked
bounds on one angle instead of all three.
This commit is contained in:
2023-03-23 23:42:15 +13:00
parent 1111ce3472
commit 8a5c9f1f6e

View File

@@ -2439,6 +2439,17 @@ static float p_abf_compute_gradient(PAbfSystem *sys, PChart *chart)
return norm;
}
static void p_abf_adjust_alpha(PAbfSystem *sys,
const int id,
const float dlambda1,
const float pre)
{
float alpha = sys->alpha[id];
const float dalpha = (sys->bAlpha[id] - dlambda1);
alpha += dalpha / sys->weight[id] - pre;
sys->alpha[id] = clamp_f(alpha, 0.0f, float(M_PI));
}
static bool p_abf_matrix_invert(PAbfSystem *sys, PChart *chart)
{
int ninterior = sys->ninterior;
@@ -2596,11 +2607,11 @@ static bool p_abf_matrix_invert(PAbfSystem *sys, PChart *chart)
if (success) {
for (PFace *f = chart->faces; f; f = f->nextlink) {
float dlambda1, pre[3], dalpha;
float pre[3];
PEdge *e1 = f->edge, *e2 = e1->next, *e3 = e2->next;
PVert *v1 = e1->vert, *v2 = e2->vert, *v3 = e3->vert;
pre[0] = pre[1] = pre[2] = 0.0;
pre[0] = pre[1] = pre[2] = 0.0f;
if (v1->flag & PVERT_INTERIOR) {
float x = EIG_linear_solver_variable_get(context, 0, v1->u.id);
@@ -2626,30 +2637,14 @@ static bool p_abf_matrix_invert(PAbfSystem *sys, PChart *chart)
pre[2] += sys->J2dt[e3->u.id][2] * x;
}
dlambda1 = pre[0] + pre[1] + pre[2];
float dlambda1 = pre[0] + pre[1] + pre[2];
dlambda1 = sys->dstar[f->u.id] * (sys->bstar[f->u.id] - dlambda1);
sys->lambdaTriangle[f->u.id] += dlambda1;
dalpha = (sys->bAlpha[e1->u.id] - dlambda1);
sys->alpha[e1->u.id] += dalpha / sys->weight[e1->u.id] - pre[0];
dalpha = (sys->bAlpha[e2->u.id] - dlambda1);
sys->alpha[e2->u.id] += dalpha / sys->weight[e2->u.id] - pre[1];
dalpha = (sys->bAlpha[e3->u.id] - dlambda1);
sys->alpha[e3->u.id] += dalpha / sys->weight[e3->u.id] - pre[2];
/* clamp */
PEdge *e = f->edge;
do {
if (sys->alpha[e->u.id] > float(M_PI)) {
sys->alpha[e->u.id] = float(M_PI);
}
else if (sys->alpha[e->u.id] < 0.0f) {
sys->alpha[e->u.id] = 0.0f;
}
} while (e != f->edge);
p_abf_adjust_alpha(sys, e1->u.id, dlambda1, pre[0]);
p_abf_adjust_alpha(sys, e2->u.id, dlambda1, pre[1]);
p_abf_adjust_alpha(sys, e3->u.id, dlambda1, pre[2]);
}
for (int i = 0; i < ninterior; i++) {