Fix T81988: Surface Deform "Bind" causes vertices to spike
Surface deform weight calculation assigned weights in a non-uniform way that caused vertices to deform upon binding. This was caused by the face-corner angle being used in calculations which where squared & scaled. Causing a triangle fan of many thin faces to have a much greater influence compared to the same shape made from a single triangle. Change the calculation of the weight so each face-corner is scaled by it's angle.
This commit is contained in:
parent
d93a6cdf00
commit
fc9f1b1754
Notes:
blender-bot
2023-02-14 02:22:13 +01:00
Referenced by issue #81988, Surface Deform modifier results in arbitrary vertices extending away from the object's origin, rather than responding to the target mesh
|
@ -424,15 +424,9 @@ static void freeBindData(SDefBindWeightData *const bwdata)
|
|||
MEM_freeN(bwdata);
|
||||
}
|
||||
|
||||
BLI_INLINE float computeAngularWeight(const float point_angle, const float edgemid_angle)
|
||||
BLI_INLINE float computeAngularWeight(const float point_angle)
|
||||
{
|
||||
float weight;
|
||||
|
||||
weight = point_angle;
|
||||
weight /= edgemid_angle;
|
||||
weight *= M_PI_2;
|
||||
|
||||
return sinf(weight);
|
||||
return sinf(point_angle * M_PI_2);
|
||||
}
|
||||
|
||||
BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data,
|
||||
|
@ -658,15 +652,12 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data,
|
|||
|
||||
/* Compute angular weight component */
|
||||
if (epolys->num == 1) {
|
||||
ang_weights[0] = computeAngularWeight(bpolys[0]->point_edgemid_angles[edge_on_poly[0]],
|
||||
bpolys[0]->edgemid_angle);
|
||||
ang_weights[0] = computeAngularWeight(bpolys[0]->point_edgemid_angles[edge_on_poly[0]]);
|
||||
bpolys[0]->weight_angular *= ang_weights[0] * ang_weights[0];
|
||||
}
|
||||
else if (epolys->num == 2) {
|
||||
ang_weights[0] = computeAngularWeight(bpolys[0]->point_edgemid_angles[edge_on_poly[0]],
|
||||
bpolys[0]->edgemid_angle);
|
||||
ang_weights[1] = computeAngularWeight(bpolys[1]->point_edgemid_angles[edge_on_poly[1]],
|
||||
bpolys[1]->edgemid_angle);
|
||||
ang_weights[0] = computeAngularWeight(bpolys[0]->point_edgemid_angles[edge_on_poly[0]]);
|
||||
ang_weights[1] = computeAngularWeight(bpolys[1]->point_edgemid_angles[edge_on_poly[1]]);
|
||||
|
||||
bpolys[0]->weight_angular *= ang_weights[0] * ang_weights[1];
|
||||
bpolys[1]->weight_angular *= ang_weights[0] * ang_weights[1];
|
||||
|
@ -707,9 +698,14 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data,
|
|||
bpoly->dominant_angle_weight = sinf(bpoly->dominant_angle_weight * M_PI_2);
|
||||
|
||||
/* Compute quadratic angular scale interpolation weight */
|
||||
scale_weight = bpoly->point_edgemid_angles[bpoly->dominant_edge] / bpoly->edgemid_angle;
|
||||
scale_weight /= scale_weight +
|
||||
(bpoly->point_edgemid_angles[!bpoly->dominant_edge] / bpoly->edgemid_angle);
|
||||
{
|
||||
const float edge_angle_a = bpoly->point_edgemid_angles[bpoly->dominant_edge];
|
||||
const float edge_angle_b = bpoly->point_edgemid_angles[!bpoly->dominant_edge];
|
||||
/* Clamp so skinny faces with near zero `edgemid_angle`
|
||||
* won't cause numeric problems. see T81988. */
|
||||
scale_weight = edge_angle_a / max_ff(edge_angle_a, bpoly->edgemid_angle);
|
||||
scale_weight /= scale_weight + (edge_angle_b / max_ff(edge_angle_b, bpoly->edgemid_angle));
|
||||
}
|
||||
|
||||
sqr = scale_weight * scale_weight;
|
||||
inv_sqr = 1.0f - scale_weight;
|
||||
|
@ -776,6 +772,11 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data,
|
|||
bpoly->weight = 1.0f / bpoly->weight_angular / bpoly->weight_dist_proj / bpoly->weight_dist;
|
||||
}
|
||||
|
||||
/* Apply after other kinds of scaling so the faces corner angle is always
|
||||
* scaled in a uniform way, preventing heavily sub-divided triangle fans
|
||||
* from having a lop-sided influence on the weighting, see T81988. */
|
||||
bpoly->weight *= bpoly->edgemid_angle / M_PI;
|
||||
|
||||
tot_weight += bpoly->weight;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue