Fix #126271: Prevent comparing a curve index mask to a point span
The `has_anything_selected` function has a variant that takes just an index mask and compares that to all selection attributes it can find, regardless of which domain they are on. In this case the bezier handle selection attributes were stored on the Curve domain while the selection domain has already been switched to Point. Now the `has_anything_selected` function always expects a domain so it can check for attributes on that same domain. Bezier handle selection does not make sense on the point domain, but the way curve selection is written makes it difficult to prevent the creation of the attribute on Curve domain. It's also not generally prohibited (user can still create that attribute) so selection code should handle this case robustly. Pull Request: https://projects.blender.org/blender/blender/pulls/126543
This commit is contained in:
@@ -404,21 +404,18 @@ bool has_anything_selected(const bke::CurvesGeometry &curves)
|
||||
}
|
||||
|
||||
bool has_anything_selected(const bke::CurvesGeometry &curves, bke::AttrDomain selection_domain)
|
||||
{
|
||||
return has_anything_selected(
|
||||
curves, selection_domain, IndexRange(curves.attributes().domain_size(selection_domain)));
|
||||
}
|
||||
|
||||
bool has_anything_selected(const bke::CurvesGeometry &curves,
|
||||
bke::AttrDomain selection_domain,
|
||||
const IndexMask &mask)
|
||||
{
|
||||
for (const StringRef selection_name : get_curves_selection_attribute_names(curves)) {
|
||||
const VArray<bool> selection = *curves.attributes().lookup<bool>(selection_name,
|
||||
selection_domain);
|
||||
if (!selection || contains(selection, selection.index_range(), true)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool has_anything_selected(const bke::CurvesGeometry &curves, const IndexMask &mask)
|
||||
{
|
||||
for (const StringRef selection_name : get_curves_selection_attribute_names(curves)) {
|
||||
const VArray<bool> selection = *curves.attributes().lookup<bool>(selection_name);
|
||||
if (!selection || contains(selection, mask, true)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -212,8 +212,8 @@ static int select_random_exec(bContext *C, wmOperator *op)
|
||||
ratio,
|
||||
memory);
|
||||
|
||||
const bool was_anything_selected = ed::curves::has_anything_selected(curves,
|
||||
selectable_elements);
|
||||
const bool was_anything_selected = ed::curves::has_anything_selected(
|
||||
curves, selection_domain, selectable_elements);
|
||||
bke::GSpanAttributeWriter selection = ed::curves::ensure_selection_attribute(
|
||||
curves, selection_domain, CD_PROP_BOOL);
|
||||
if (!was_anything_selected) {
|
||||
@@ -307,8 +307,8 @@ static int select_ends_exec(bContext *C, wmOperator *op)
|
||||
|
||||
const IndexMask selectable_points = ed::greasepencil::retrieve_editable_points(
|
||||
*object, info.drawing, info.layer_index, memory);
|
||||
const bool was_anything_selected = ed::curves::has_anything_selected(curves,
|
||||
selectable_points);
|
||||
const bool was_anything_selected = ed::curves::has_anything_selected(
|
||||
curves, bke::AttrDomain::Point, selectable_points);
|
||||
bke::GSpanAttributeWriter selection = ed::curves::ensure_selection_attribute(
|
||||
curves, bke::AttrDomain::Point, CD_PROP_BOOL);
|
||||
if (!was_anything_selected) {
|
||||
|
||||
@@ -193,7 +193,9 @@ void fill_selection_true(GMutableSpan selection, const IndexMask &mask);
|
||||
*/
|
||||
bool has_anything_selected(const bke::CurvesGeometry &curves);
|
||||
bool has_anything_selected(const bke::CurvesGeometry &curves, bke::AttrDomain selection_domain);
|
||||
bool has_anything_selected(const bke::CurvesGeometry &curves, const IndexMask &mask);
|
||||
bool has_anything_selected(const bke::CurvesGeometry &curves,
|
||||
bke::AttrDomain selection_domain,
|
||||
const IndexMask &mask);
|
||||
|
||||
/**
|
||||
* Return true if any element in the span is selected, on either domain with either type.
|
||||
|
||||
@@ -3320,7 +3320,7 @@ static bool ed_grease_pencil_select_pick(bContext *C,
|
||||
continue;
|
||||
}
|
||||
bke::CurvesGeometry &curves = info.drawing.strokes_for_write();
|
||||
if (!ed::curves::has_anything_selected(curves, elements)) {
|
||||
if (!ed::curves::has_anything_selected(curves, selection_domain, elements)) {
|
||||
continue;
|
||||
}
|
||||
ed::curves::foreach_selection_attribute_writer(
|
||||
|
||||
Reference in New Issue
Block a user