From 1a540f8c519d4938eaef9599f1c36e4e20e6512b Mon Sep 17 00:00:00 2001 From: illua1 Date: Wed, 12 Apr 2023 16:29:01 +0300 Subject: [PATCH 1/4] init --- .../geometry/nodes/node_geo_blur_attribute.cc | 86 +++++++++++-------- 1 file changed, 48 insertions(+), 38 deletions(-) diff --git a/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc b/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc index 7adbdce52cb..eefdc8bb67e 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc @@ -249,8 +249,9 @@ template static void blur_on_mesh_exec(const Span neighbor_weights, const Span> neighbors_map, const int iterations, - MutableSpan main_buffer, - MutableSpan tmp_buffer) + const MutableSpan main_buffer, + const MutableSpan tmp_buffer, + bool &r_tmp_buffer_is_result) { MutableSpan src = main_buffer; MutableSpan dst = tmp_buffer; @@ -271,13 +272,8 @@ static void blur_on_mesh_exec(const Span neighbor_weights, std::swap(src, dst); } - /* The last computed values are in #src now. If the main buffer is #dst, the values have to be - * copied once more. */ if (dst.data() == main_buffer.data()) { - threading::parallel_for(dst.index_range(), 1024, [&](const IndexRange range) { - initialized_copy_n( - src.data() + range.start(), range.size(), main_buffer.data() + range.start()); - }); + r_tmp_buffer_is_result = true; } } @@ -285,8 +281,9 @@ static void blur_on_mesh(const Mesh &mesh, const eAttrDomain domain, const int iterations, const Span neighbor_weights, - GMutableSpan main_buffer, - GMutableSpan tmp_buffer) + const GMutableSpan main_buffer, + const GMutableSpan tmp_buffer, + bool &tmp_buffer_is_result) { Array> neighbors_map = create_mesh_map(mesh, domain, neighbor_weights.index_range()); if (neighbors_map.is_empty()) { @@ -299,7 +296,8 @@ static void blur_on_mesh(const Mesh &mesh, neighbors_map, iterations, main_buffer.typed(), - tmp_buffer.typed()); + tmp_buffer.typed(), + tmp_buffer_is_result); } }); } @@ -308,8 +306,9 @@ template static void blur_on_curve_exec(const bke::CurvesGeometry &curves, const Span neighbor_weights, const int iterations, - MutableSpan main_buffer, - MutableSpan tmp_buffer) + const MutableSpan main_buffer, + const MutableSpan tmp_buffer, + bool &r_tmp_buffer_is_result) { MutableSpan src = main_buffer; MutableSpan dst = tmp_buffer; @@ -339,51 +338,47 @@ static void blur_on_curve_exec(const bke::CurvesGeometry &curves, const float first_neighbor_weight = neighbor_weights[first_i]; const int last_i = points.last(); const float last_neighbor_weight = neighbor_weights[last_i]; + + /* First point. */ + mixer.set(first_i, src[first_i], 1.0f); + mixer.mix_in(first_i, src[first_i + 1], first_neighbor_weight); + /* Last point. */ + mixer.set(last_i, src[last_i], 1.0f); + mixer.mix_in(last_i, src[last_i - 1], last_neighbor_weight); + if (cyclic[curve_i]) { /* First point. */ - mixer.set(first_i, src[first_i], 1.0f); - mixer.mix_in(first_i, src[first_i + 1], first_neighbor_weight); mixer.mix_in(first_i, src[last_i], first_neighbor_weight); /* Last point. */ - mixer.set(last_i, src[last_i], 1.0f); - mixer.mix_in(last_i, src[last_i - 1], last_neighbor_weight); mixer.mix_in(last_i, src[first_i], last_neighbor_weight); } - else { - /* First point. */ - mixer.set(first_i, src[first_i], 1.0f); - mixer.mix_in(first_i, src[first_i + 1], first_neighbor_weight); - /* Last point. */ - mixer.set(last_i, src[last_i], 1.0f); - mixer.mix_in(last_i, src[last_i - 1], last_neighbor_weight); - } } mixer.finalize(points_by_curve[range]); }); std::swap(src, dst); } - /* The last computed values are in #src now. If the main buffer is #dst, the values have to be - * copied once more. */ if (dst.data() == main_buffer.data()) { - threading::parallel_for(dst.index_range(), 1024, [&](const IndexRange range) { - initialized_copy_n( - src.data() + range.start(), range.size(), main_buffer.data() + range.start()); - }); + r_tmp_buffer_is_result = true; } } static void blur_on_curves(const bke::CurvesGeometry &curves, const int iterations, const Span neighbor_weights, - GMutableSpan main_buffer, - GMutableSpan tmp_buffer) + const GMutableSpan main_buffer, + const GMutableSpan tmp_buffer, + bool &r_tmp_buffer_is_result) { attribute_math::convert_to_static_type(main_buffer.type(), [&](auto dummy) { using T = decltype(dummy); if constexpr (!std::is_same_v) { - blur_on_curve_exec( - curves, neighbor_weights, iterations, main_buffer.typed(), tmp_buffer.typed()); + blur_on_curve_exec(curves, + neighbor_weights, + iterations, + main_buffer.typed(), + tmp_buffer.typed(), + r_tmp_buffer_is_result); } }); } @@ -428,19 +423,31 @@ class BlurAttributeFieldInput final : public bke::GeometryFieldInput { VArraySpan neighbor_weights = evaluator.get_evaluated(1); GArray<> tmp_buffer(*type_, domain_size); + bool tmp_buffer_is_result = false; + switch (context.type()) { case GEO_COMPONENT_TYPE_MESH: if (ELEM(context.domain(), ATTR_DOMAIN_POINT, ATTR_DOMAIN_EDGE, ATTR_DOMAIN_FACE)) { if (const Mesh *mesh = context.mesh()) { - blur_on_mesh( - *mesh, context.domain(), iterations_, neighbor_weights, main_buffer, tmp_buffer); + blur_on_mesh(*mesh, + context.domain(), + iterations_, + neighbor_weights, + main_buffer, + tmp_buffer, + tmp_buffer_is_result); } } break; case GEO_COMPONENT_TYPE_CURVE: if (context.domain() == ATTR_DOMAIN_POINT) { if (const bke::CurvesGeometry *curves = context.curves()) { - blur_on_curves(*curves, iterations_, neighbor_weights, main_buffer, tmp_buffer); + blur_on_curves(*curves, + iterations_, + neighbor_weights, + main_buffer, + tmp_buffer, + tmp_buffer_is_result); } } break; @@ -448,6 +455,9 @@ class BlurAttributeFieldInput final : public bke::GeometryFieldInput { break; } + if (tmp_buffer_is_result) { + return GVArray::ForGArray(std::move(tmp_buffer)); + } return GVArray::ForGArray(std::move(main_buffer)); } -- 2.30.2 From 5581c33d428e7b9d169341ea2529498ad9fc64e8 Mon Sep 17 00:00:00 2001 From: illua1 Date: Thu, 13 Apr 2023 22:10:54 +0300 Subject: [PATCH 2/4] delete bool ¶metr, just return last buffer as span --- .../geometry/nodes/node_geo_blur_attribute.cc | 118 ++++++++---------- 1 file changed, 50 insertions(+), 68 deletions(-) diff --git a/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc b/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc index eefdc8bb67e..b721908ac08 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc @@ -246,17 +246,17 @@ static Array> create_mesh_map(const Mesh &mesh, } template -static void blur_on_mesh_exec(const Span neighbor_weights, - const Span> neighbors_map, - const int iterations, - const MutableSpan main_buffer, - const MutableSpan tmp_buffer, - bool &r_tmp_buffer_is_result) +static Span blur_on_mesh_exec(const Span neighbor_weights, + const Span> neighbors_map, + const int iterations, + const MutableSpan main_buffer, + const MutableSpan tmp_buffer) { - MutableSpan src = main_buffer; - MutableSpan dst = tmp_buffer; + MutableSpan src = tmp_buffer; + MutableSpan dst = main_buffer; for ([[maybe_unused]] const int64_t iteration : IndexRange(iterations)) { + std::swap(src, dst); attribute_math::DefaultMixer mixer{dst, IndexMask(0)}; threading::parallel_for(dst.index_range(), 1024, [&](const IndexRange range) { for (const int64_t index : range) { @@ -269,54 +269,51 @@ static void blur_on_mesh_exec(const Span neighbor_weights, } mixer.finalize(range); }); - std::swap(src, dst); } - if (dst.data() == main_buffer.data()) { - r_tmp_buffer_is_result = true; - } + return dst; } -static void blur_on_mesh(const Mesh &mesh, - const eAttrDomain domain, - const int iterations, - const Span neighbor_weights, - const GMutableSpan main_buffer, - const GMutableSpan tmp_buffer, - bool &tmp_buffer_is_result) +static GSpan blur_on_mesh(const Mesh &mesh, + const eAttrDomain domain, + const int iterations, + const Span neighbor_weights, + const GMutableSpan main_buffer, + const GMutableSpan tmp_buffer) { Array> neighbors_map = create_mesh_map(mesh, domain, neighbor_weights.index_range()); if (neighbors_map.is_empty()) { - return; + return main_buffer; } + GSpan result_buffer; attribute_math::convert_to_static_type(main_buffer.type(), [&](auto dummy) { using T = decltype(dummy); if constexpr (!std::is_same_v) { - blur_on_mesh_exec(neighbor_weights, - neighbors_map, - iterations, - main_buffer.typed(), - tmp_buffer.typed(), - tmp_buffer_is_result); + result_buffer = blur_on_mesh_exec(neighbor_weights, + neighbors_map, + iterations, + main_buffer.typed(), + tmp_buffer.typed()); } }); + return result_buffer; } template -static void blur_on_curve_exec(const bke::CurvesGeometry &curves, - const Span neighbor_weights, - const int iterations, - const MutableSpan main_buffer, - const MutableSpan tmp_buffer, - bool &r_tmp_buffer_is_result) +static Span blur_on_curve_exec(const bke::CurvesGeometry &curves, + const Span neighbor_weights, + const int iterations, + const MutableSpan main_buffer, + const MutableSpan tmp_buffer) { - MutableSpan src = main_buffer; - MutableSpan dst = tmp_buffer; + MutableSpan src = tmp_buffer; + MutableSpan dst = main_buffer; const OffsetIndices points_by_curve = curves.points_by_curve(); const VArray cyclic = curves.cyclic(); for ([[maybe_unused]] const int iteration : IndexRange(iterations)) { + std::swap(src, dst); attribute_math::DefaultMixer mixer{dst, IndexMask(0)}; threading::parallel_for(curves.curves_range(), 256, [&](const IndexRange range) { for (const int curve_i : range) { @@ -355,32 +352,26 @@ static void blur_on_curve_exec(const bke::CurvesGeometry &curves, } mixer.finalize(points_by_curve[range]); }); - std::swap(src, dst); } - if (dst.data() == main_buffer.data()) { - r_tmp_buffer_is_result = true; - } + return dst; } -static void blur_on_curves(const bke::CurvesGeometry &curves, - const int iterations, - const Span neighbor_weights, - const GMutableSpan main_buffer, - const GMutableSpan tmp_buffer, - bool &r_tmp_buffer_is_result) +static GSpan blur_on_curves(const bke::CurvesGeometry &curves, + const int iterations, + const Span neighbor_weights, + const GMutableSpan main_buffer, + const GMutableSpan tmp_buffer) { + GSpan result_buffer; attribute_math::convert_to_static_type(main_buffer.type(), [&](auto dummy) { using T = decltype(dummy); if constexpr (!std::is_same_v) { - blur_on_curve_exec(curves, - neighbor_weights, - iterations, - main_buffer.typed(), - tmp_buffer.typed(), - r_tmp_buffer_is_result); + result_buffer = blur_on_curve_exec( + curves, neighbor_weights, iterations, main_buffer.typed(), tmp_buffer.typed()); } }); + return result_buffer; } class BlurAttributeFieldInput final : public bke::GeometryFieldInput { @@ -423,31 +414,21 @@ class BlurAttributeFieldInput final : public bke::GeometryFieldInput { VArraySpan neighbor_weights = evaluator.get_evaluated(1); GArray<> tmp_buffer(*type_, domain_size); - bool tmp_buffer_is_result = false; - + GSpan result_buffer; switch (context.type()) { case GEO_COMPONENT_TYPE_MESH: if (ELEM(context.domain(), ATTR_DOMAIN_POINT, ATTR_DOMAIN_EDGE, ATTR_DOMAIN_FACE)) { if (const Mesh *mesh = context.mesh()) { - blur_on_mesh(*mesh, - context.domain(), - iterations_, - neighbor_weights, - main_buffer, - tmp_buffer, - tmp_buffer_is_result); + result_buffer = blur_on_mesh( + *mesh, context.domain(), iterations_, neighbor_weights, main_buffer, tmp_buffer); } } break; case GEO_COMPONENT_TYPE_CURVE: if (context.domain() == ATTR_DOMAIN_POINT) { if (const bke::CurvesGeometry *curves = context.curves()) { - blur_on_curves(*curves, - iterations_, - neighbor_weights, - main_buffer, - tmp_buffer, - tmp_buffer_is_result); + result_buffer = blur_on_curves( + *curves, iterations_, neighbor_weights, main_buffer, tmp_buffer); } } break; @@ -455,10 +436,11 @@ class BlurAttributeFieldInput final : public bke::GeometryFieldInput { break; } - if (tmp_buffer_is_result) { - return GVArray::ForGArray(std::move(tmp_buffer)); + BLI_assert(ELEM(result_buffer.data(), tmp_buffer.data(), main_buffer.data())); + if (result_buffer.data() == main_buffer.data()) { + return GVArray::ForGArray(std::move(main_buffer)); } - return GVArray::ForGArray(std::move(main_buffer)); + return GVArray::ForGArray(std::move(tmp_buffer)); } void for_each_field_input_recursive(FunctionRef fn) const override -- 2.30.2 From 517c4d27b5f4c126ff87cf168cd74febe6c93f90 Mon Sep 17 00:00:00 2001 From: illua1 Date: Thu, 13 Apr 2023 22:14:48 +0300 Subject: [PATCH 3/4] rename buffers to A and B --- .../geometry/nodes/node_geo_blur_attribute.cc | 61 +++++++++---------- 1 file changed, 29 insertions(+), 32 deletions(-) diff --git a/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc b/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc index b721908ac08..603730a3398 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc @@ -249,11 +249,11 @@ template static Span blur_on_mesh_exec(const Span neighbor_weights, const Span> neighbors_map, const int iterations, - const MutableSpan main_buffer, - const MutableSpan tmp_buffer) + const MutableSpan buffer_a, + const MutableSpan buffer_b) { - MutableSpan src = tmp_buffer; - MutableSpan dst = main_buffer; + MutableSpan src = buffer_b; + MutableSpan dst = buffer_a; for ([[maybe_unused]] const int64_t iteration : IndexRange(iterations)) { std::swap(src, dst); @@ -278,22 +278,19 @@ static GSpan blur_on_mesh(const Mesh &mesh, const eAttrDomain domain, const int iterations, const Span neighbor_weights, - const GMutableSpan main_buffer, - const GMutableSpan tmp_buffer) + const GMutableSpan buffer_a, + const GMutableSpan buffer_b) { Array> neighbors_map = create_mesh_map(mesh, domain, neighbor_weights.index_range()); if (neighbors_map.is_empty()) { - return main_buffer; + return buffer_a; } GSpan result_buffer; - attribute_math::convert_to_static_type(main_buffer.type(), [&](auto dummy) { + attribute_math::convert_to_static_type(buffer_a.type(), [&](auto dummy) { using T = decltype(dummy); if constexpr (!std::is_same_v) { - result_buffer = blur_on_mesh_exec(neighbor_weights, - neighbors_map, - iterations, - main_buffer.typed(), - tmp_buffer.typed()); + result_buffer = blur_on_mesh_exec( + neighbor_weights, neighbors_map, iterations, buffer_a.typed(), buffer_b.typed()); } }); return result_buffer; @@ -303,11 +300,11 @@ template static Span blur_on_curve_exec(const bke::CurvesGeometry &curves, const Span neighbor_weights, const int iterations, - const MutableSpan main_buffer, - const MutableSpan tmp_buffer) + const MutableSpan buffer_a, + const MutableSpan buffer_b) { - MutableSpan src = tmp_buffer; - MutableSpan dst = main_buffer; + MutableSpan src = buffer_b; + MutableSpan dst = buffer_a; const OffsetIndices points_by_curve = curves.points_by_curve(); const VArray cyclic = curves.cyclic(); @@ -360,15 +357,15 @@ static Span blur_on_curve_exec(const bke::CurvesGeometry &curves, static GSpan blur_on_curves(const bke::CurvesGeometry &curves, const int iterations, const Span neighbor_weights, - const GMutableSpan main_buffer, - const GMutableSpan tmp_buffer) + const GMutableSpan buffer_a, + const GMutableSpan buffer_b) { GSpan result_buffer; - attribute_math::convert_to_static_type(main_buffer.type(), [&](auto dummy) { + attribute_math::convert_to_static_type(buffer_a.type(), [&](auto dummy) { using T = decltype(dummy); if constexpr (!std::is_same_v) { result_buffer = blur_on_curve_exec( - curves, neighbor_weights, iterations, main_buffer.typed(), tmp_buffer.typed()); + curves, neighbor_weights, iterations, buffer_a.typed(), buffer_b.typed()); } }); return result_buffer; @@ -394,25 +391,25 @@ class BlurAttributeFieldInput final : public bke::GeometryFieldInput { { const int64_t domain_size = context.attributes()->domain_size(context.domain()); - GArray<> main_buffer(*type_, domain_size); + GArray<> buffer_a(*type_, domain_size); FieldEvaluator evaluator(context, domain_size); - evaluator.add_with_destination(value_field_, main_buffer.as_mutable_span()); + evaluator.add_with_destination(value_field_, buffer_a.as_mutable_span()); evaluator.add(weight_field_); evaluator.evaluate(); /* Blurring does not make sense with a less than 2 elements. */ if (domain_size <= 1) { - return GVArray::ForGArray(std::move(main_buffer)); + return GVArray::ForGArray(std::move(buffer_a)); } if (iterations_ <= 0) { - return GVArray::ForGArray(std::move(main_buffer)); + return GVArray::ForGArray(std::move(buffer_a)); } VArraySpan neighbor_weights = evaluator.get_evaluated(1); - GArray<> tmp_buffer(*type_, domain_size); + GArray<> buffer_b(*type_, domain_size); GSpan result_buffer; switch (context.type()) { @@ -420,7 +417,7 @@ class BlurAttributeFieldInput final : public bke::GeometryFieldInput { if (ELEM(context.domain(), ATTR_DOMAIN_POINT, ATTR_DOMAIN_EDGE, ATTR_DOMAIN_FACE)) { if (const Mesh *mesh = context.mesh()) { result_buffer = blur_on_mesh( - *mesh, context.domain(), iterations_, neighbor_weights, main_buffer, tmp_buffer); + *mesh, context.domain(), iterations_, neighbor_weights, buffer_a, buffer_b); } } break; @@ -428,7 +425,7 @@ class BlurAttributeFieldInput final : public bke::GeometryFieldInput { if (context.domain() == ATTR_DOMAIN_POINT) { if (const bke::CurvesGeometry *curves = context.curves()) { result_buffer = blur_on_curves( - *curves, iterations_, neighbor_weights, main_buffer, tmp_buffer); + *curves, iterations_, neighbor_weights, buffer_a, buffer_b); } } break; @@ -436,11 +433,11 @@ class BlurAttributeFieldInput final : public bke::GeometryFieldInput { break; } - BLI_assert(ELEM(result_buffer.data(), tmp_buffer.data(), main_buffer.data())); - if (result_buffer.data() == main_buffer.data()) { - return GVArray::ForGArray(std::move(main_buffer)); + BLI_assert(ELEM(result_buffer.data(), buffer_a.data(), buffer_b.data())); + if (result_buffer.data() == buffer_a.data()) { + return GVArray::ForGArray(std::move(buffer_a)); } - return GVArray::ForGArray(std::move(tmp_buffer)); + return GVArray::ForGArray(std::move(buffer_b)); } void for_each_field_input_recursive(FunctionRef fn) const override -- 2.30.2 From 3c03958ade6449ddc8acb8d4240a8ed3c0461d22 Mon Sep 17 00:00:00 2001 From: illua1 Date: Fri, 14 Apr 2023 15:03:25 +0300 Subject: [PATCH 4/4] add comment --- source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc b/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc index 603730a3398..633654923ed 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc @@ -252,6 +252,8 @@ static Span blur_on_mesh_exec(const Span neighbor_weights, const MutableSpan buffer_a, const MutableSpan buffer_b) { + /* Source is set to buffer_b even though it is actually in buffer_a because the loop below starts + * with swapping both. */ MutableSpan src = buffer_b; MutableSpan dst = buffer_a; -- 2.30.2