Fix #134482: Grease Pencil: Correct mask for stroke interpolation

Selection mask is included in the stroke interpolation tool in
297b97f2df, however sometimes there will
be mismatches for when start/end curve count isn't the same. This fix
ensures that the interpolation operator only works on the max amount of
curves that can fit in both start and end side of the interpolation.

Pull Request: https://projects.blender.org/blender/blender/pulls/134484
This commit is contained in:
YimingWu
2025-02-13 12:45:53 +01:00
committed by Falk David
parent 6d749db0c2
commit ef844badd6
2 changed files with 14 additions and 7 deletions

View File

@@ -287,10 +287,10 @@ static bool find_curve_mapping_from_index(const GreasePencil &grease_pencil,
}
/* Discard additional elements of the larger selection. */
if (from_selection.size() > to_selection.size()) {
from_selection.slice(0, to_selection.size());
from_selection = from_selection.slice(0, to_selection.size());
}
else if (to_selection.size() > from_selection.size()) {
to_selection.slice(0, from_selection.size());
to_selection = to_selection.slice(0, from_selection.size());
}
/* By default: copy the "from" curve and ignore the "to" curve. */

View File

@@ -455,17 +455,24 @@ void interpolate_curves_with_samples(const CurvesGeometry &from_curves,
CD_PROP_FLOAT2,
CD_PROP_FLOAT3);
if (can_mix_attribute && !src_from.is_empty() && !src_to.is_empty()) {
const int max_curves = std::min(dst_curve_mask.min_array_size(),
std::min(src_from.size(), src_to.size()));
const IndexMask safe_dst_curve_mask = dst_curve_mask.slice_content(0, max_curves);
GArray<> from_samples(dst.type(), dst.size());
GArray<> to_samples(dst.type(), dst.size());
array_utils::copy(GVArray::ForSpan(src_from), dst_curve_mask, from_samples);
array_utils::copy(GVArray::ForSpan(src_to), dst_curve_mask, to_samples);
mix_arrays(from_samples, to_samples, mix_factors, dst_curve_mask, dst);
array_utils::copy(GVArray::ForSpan(src_from), safe_dst_curve_mask, from_samples);
array_utils::copy(GVArray::ForSpan(src_to), safe_dst_curve_mask, to_samples);
mix_arrays(from_samples, to_samples, mix_factors, safe_dst_curve_mask, dst);
}
else if (!src_from.is_empty()) {
array_utils::copy(GVArray::ForSpan(src_from), dst_curve_mask, dst);
const int max_curves = std::min(dst_curve_mask.min_array_size(), src_from.size());
const IndexMask safe_dst_curve_mask = dst_curve_mask.slice_content(0, max_curves);
array_utils::copy(GVArray::ForSpan(src_from), safe_dst_curve_mask, dst);
}
else if (!src_to.is_empty()) {
array_utils::copy(GVArray::ForSpan(src_to), dst_curve_mask, dst);
const int max_curves = std::min(dst_curve_mask.min_array_size(), src_to.size());
const IndexMask safe_dst_curve_mask = dst_curve_mask.slice_content(0, max_curves);
array_utils::copy(GVArray::ForSpan(src_to), safe_dst_curve_mask, dst);
}
}