Fix: Vertex Paint average brush produces incorrect results

This commit moves the initialization of the node-sized accumulation
array out of the parallel loop to avoid odd optimization errors when
differing between debug and release builds as well as errors due to
integer overflow in both builds.

Additionally it only accumulates results from affected nodes.

Pull Request: https://projects.blender.org/blender/blender/pulls/134720
This commit is contained in:
Sean Kim
2025-02-19 22:07:34 +01:00
committed by Sean Kim
parent f3377aa7e8
commit 0acd86abca

View File

@@ -1567,12 +1567,10 @@ static void calculate_average_color(VPaintData &vpd,
using Blend = typename Traits::BlendType;
const Span<Color> colors = attribute.typed<T>().template cast<Color>();
Array<VPaintAverageAccum<Blend>> accum(nodes.size());
Array<VPaintAverageAccum<Blend>> accum(nodes.size(), {0, {0, 0, 0}});
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
VPaintAverageAccum<Blend> &accum2 = accum[i];
accum2.len = 0;
memset(accum2.value, 0, sizeof(accum2.value));
LocalData &tls = all_tls.local();
const Span<int> verts = nodes[i].verts();
tls.factors.resize(verts.size());
@@ -1620,12 +1618,12 @@ static void calculate_average_color(VPaintData &vpd,
Blend accum_value[3] = {0};
Color blend(0, 0, 0, 0);
for (int i = 0; i < nodes.size(); i++) {
node_mask.foreach_index([&](const int i) {
accum_len += accum[i].len;
accum_value[0] += accum[i].value[0];
accum_value[1] += accum[i].value[1];
accum_value[2] += accum[i].value[2];
}
});
if (accum_len != 0) {
blend.r = Traits::round(sqrtf(Traits::divide_round(accum_value[0], accum_len)));
blend.g = Traits::round(sqrtf(Traits::divide_round(accum_value[1], accum_len)));