Fix: Curves: Crash in transform code for non bézier curves

This caused a crash in grease pencil when trying to transform strokes (poly curves).
The code assumed that the left and right handle indices existed.

Pull Request: https://projects.blender.org/blender/blender/pulls/123311
This commit is contained in:
Falk David 2024-06-18 19:08:11 +02:00 committed by Falk David
parent feed10a4c2
commit 10b1e45ca8

@ -262,9 +262,10 @@ static OffsetIndices<int> recent_position_offsets(TransCustomData &custom_data,
}
/**
* Creates map of indices to `tc.data` representing curve in layout
* [L0, P0, R0, L1, P1, R1, L2,P2, R2], where [P0, P1, P2], [L0, L1, L2] and [R0, R1, R2] are
* positions, left handles and right handles respectively.
* Creates map of indices to `tc.data` representing the curves.
* For bezier curves it uses the layout [L0, P0, R0, L1, P1, R1, L2, P2, R2], where [P0, P1, P2],
* [L0, L1, L2] and [R0, R1, R2] are positions, left handles and right handles respectively.
* Other curve types just use the positions [P0, P1, ..., Pn] of the control points directly.
*/
static void fill_map(const CurveType curve_type,
const IndexRange curve_points,
@ -272,24 +273,22 @@ static void fill_map(const CurveType curve_type,
const int handles_offset,
MutableSpan<int> map)
{
const int attr_num = (curve_type == CURVE_TYPE_BEZIER) ? 3 : 1;
const int left_handle_index = handles_offset + position_offsets_in_td[1].start();
const int position_index = curve_points.start() + position_offsets_in_td[0].start();
const int right_handle_index = handles_offset + position_offsets_in_td[2].start();
std::array<int, 3> first_per_attr = {curve_type == CURVE_TYPE_BEZIER ? left_handle_index :
position_index,
/* Next two unused for non Bezier curves. */
position_index,
right_handle_index};
threading::parallel_for(curve_points.index_range(), 4096, [&](const IndexRange range) {
for (const int i : range) {
for (const int attr : IndexRange(attr_num)) {
map[i * attr_num + attr] = first_per_attr[attr] + i;
if (curve_type == CURVE_TYPE_BEZIER) {
const int left_handle_index = handles_offset + position_offsets_in_td[1].start();
const int right_handle_index = handles_offset + position_offsets_in_td[2].start();
std::array<int, 3> first_per_attr = {left_handle_index, position_index, right_handle_index};
threading::parallel_for(curve_points.index_range(), 4096, [&](const IndexRange range) {
for (const int i : range) {
for (const int attr : IndexRange(3)) {
map[i * 3 + attr] = first_per_attr[attr] + i;
}
}
}
});
});
}
else {
array_utils::fill_index_range(map, position_index);
}
}
} // namespace blender::ed::transform::curves