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:
@@ -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++) {
|
||||
|
Reference in New Issue
Block a user