Fix: Grease Pencil: Select Grouped not selecting bezier handles
This makes it so that the `Select Grouped` operator will selected Bezier handles. And Points with handles selected will be used included in the group. Part of #121574 Pull Request: https://projects.blender.org/blender/blender/pulls/144894
This commit is contained in:
committed by
casey-bianco-davis
parent
4d7042a46e
commit
899a8bcdac
@@ -586,30 +586,43 @@ static const EnumPropertyItem select_similar_mode_items[] = {
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
void insert_selected_values(const bke::CurvesGeometry &curves,
|
||||
void insert_selected_values(Object *object,
|
||||
const MutableDrawingInfo &info,
|
||||
const bke::AttrDomain domain,
|
||||
const StringRef attribute_id,
|
||||
const int handle_display,
|
||||
blender::Set<T> &r_value_set)
|
||||
{
|
||||
T default_value;
|
||||
CPPType::get<T>().default_construct(&default_value);
|
||||
|
||||
const bke::CurvesGeometry &curves = info.drawing.strokes();
|
||||
const bke::AttributeAccessor attributes = curves.attributes();
|
||||
const VArraySpan<bool> selection = *attributes.lookup_or_default<bool>(
|
||||
".selection", domain, true);
|
||||
const VArraySpan<T> values = *attributes.lookup_or_default<T>(
|
||||
attribute_id, domain, default_value);
|
||||
|
||||
threading::EnumerableThreadSpecific<Set<T>> value_set_by_thread;
|
||||
threading::parallel_for(
|
||||
IndexRange(attributes.domain_size(domain)), 1024, [&](const IndexRange range) {
|
||||
Set<T> &local_value_set = value_set_by_thread.local();
|
||||
for (const int i : range) {
|
||||
if (selection[i]) {
|
||||
local_value_set.add(values[i]);
|
||||
}
|
||||
}
|
||||
});
|
||||
IndexMaskMemory memory;
|
||||
if (domain == bke::AttrDomain::Point) {
|
||||
const IndexMask points = ed::greasepencil::retrieve_editable_and_all_selected_points(
|
||||
*object, info.drawing, info.layer_index, handle_display, memory);
|
||||
points.foreach_index(GrainSize(1024), [&](const int index) {
|
||||
Set<T> &local_value_set = value_set_by_thread.local();
|
||||
local_value_set.add(values[index]);
|
||||
});
|
||||
}
|
||||
else if (domain == bke::AttrDomain::Curve) {
|
||||
const IndexMask strokes = ed::greasepencil::retrieve_editable_and_selected_strokes(
|
||||
*object, info.drawing, info.layer_index, memory);
|
||||
|
||||
strokes.foreach_index(GrainSize(1024), [&](const int index) {
|
||||
Set<T> &local_value_set = value_set_by_thread.local();
|
||||
local_value_set.add(values[index]);
|
||||
});
|
||||
}
|
||||
else {
|
||||
BLI_assert_unreachable();
|
||||
}
|
||||
|
||||
for (const Set<T> &local_value_set : value_set_by_thread) {
|
||||
/* TODO is there a union function that can do this more efficiently? */
|
||||
@@ -625,6 +638,7 @@ static void select_similar_by_value(Scene *scene,
|
||||
GreasePencil &grease_pencil,
|
||||
const bke::AttrDomain selection_domain,
|
||||
const StringRef attribute_id,
|
||||
const int handle_display,
|
||||
float threshold,
|
||||
DistanceFn distance_fn)
|
||||
{
|
||||
@@ -639,33 +653,37 @@ static void select_similar_by_value(Scene *scene,
|
||||
blender::Set<T> selected_values;
|
||||
for (const MutableDrawingInfo &info : drawings) {
|
||||
insert_selected_values(
|
||||
info.drawing.strokes(), selection_domain, attribute_id, selected_values);
|
||||
object, info, selection_domain, attribute_id, handle_display, selected_values);
|
||||
}
|
||||
|
||||
threading::parallel_for_each(drawings, [&](const MutableDrawingInfo &info) {
|
||||
bke::CurvesGeometry &curves = info.drawing.strokes_for_write();
|
||||
bke::GSpanAttributeWriter selection_writer = ed::curves::ensure_selection_attribute(
|
||||
curves, selection_domain, bke::AttrType::Bool);
|
||||
MutableSpan<bool> selection = selection_writer.span.typed<bool>();
|
||||
const VArraySpan<T> values = *curves.attributes().lookup_or_default<T>(
|
||||
attribute_id, selection_domain, default_value);
|
||||
|
||||
IndexMaskMemory memory;
|
||||
const IndexMask mask = ed::greasepencil::retrieve_editable_points(
|
||||
*object, info.drawing, info.layer_index, memory);
|
||||
bke::CurvesGeometry &curves = info.drawing.strokes_for_write();
|
||||
const VArraySpan<T> values = *curves.attributes().lookup_or_default<T>(
|
||||
attribute_id, selection_domain, default_value);
|
||||
|
||||
mask.foreach_index(GrainSize(1024), [&](const int index) {
|
||||
if (selection[index]) {
|
||||
return;
|
||||
}
|
||||
for (const T &test_value : selected_values) {
|
||||
if (distance_fn(values[index], test_value) <= threshold) {
|
||||
selection[index] = true;
|
||||
Span<StringRef> selection_attribute_names = ed::curves::get_curves_selection_attribute_names(
|
||||
curves);
|
||||
for (const int i : selection_attribute_names.index_range()) {
|
||||
bke::GSpanAttributeWriter selection_writer = ed::curves::ensure_selection_attribute(
|
||||
curves, selection_domain, bke::AttrType::Bool, selection_attribute_names[i]);
|
||||
MutableSpan<bool> selection = selection_writer.span.typed<bool>();
|
||||
|
||||
mask.foreach_index(GrainSize(1024), [&](const int index) {
|
||||
if (selection[index]) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
for (const T &test_value : selected_values) {
|
||||
if (distance_fn(values[index], test_value) <= threshold) {
|
||||
selection[index] = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
selection_writer.finish();
|
||||
selection_writer.finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -710,10 +728,12 @@ static wmOperatorStatus select_similar_exec(bContext *C, wmOperator *op)
|
||||
const SelectSimilarMode mode = SelectSimilarMode(RNA_enum_get(op->ptr, "mode"));
|
||||
const float threshold = RNA_float_get(op->ptr, "threshold");
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
View3D *v3d = CTX_wm_view3d(C);
|
||||
Object *object = CTX_data_active_object(C);
|
||||
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(object->data);
|
||||
bke::AttrDomain selection_domain = ED_grease_pencil_selection_domain_get(scene->toolsettings,
|
||||
object);
|
||||
const int handle_display = v3d->overlay.handle_display;
|
||||
|
||||
switch (mode) {
|
||||
case SelectSimilarMode::LAYER:
|
||||
@@ -726,6 +746,7 @@ static wmOperatorStatus select_similar_exec(bContext *C, wmOperator *op)
|
||||
grease_pencil,
|
||||
selection_domain,
|
||||
"material_index",
|
||||
handle_display,
|
||||
threshold,
|
||||
[](const int a, const int b) -> float { return float(math::distance(a, b)); });
|
||||
break;
|
||||
@@ -736,6 +757,7 @@ static wmOperatorStatus select_similar_exec(bContext *C, wmOperator *op)
|
||||
grease_pencil,
|
||||
selection_domain,
|
||||
"vertex_color",
|
||||
handle_display,
|
||||
threshold,
|
||||
[](const ColorGeometry4f &a, const ColorGeometry4f &b) -> float {
|
||||
return math::distance(float4(a), float4(b));
|
||||
@@ -748,6 +770,7 @@ static wmOperatorStatus select_similar_exec(bContext *C, wmOperator *op)
|
||||
grease_pencil,
|
||||
selection_domain,
|
||||
"radius",
|
||||
handle_display,
|
||||
threshold,
|
||||
[](const float a, const float b) -> float { return math::distance(a, b); });
|
||||
break;
|
||||
@@ -758,6 +781,7 @@ static wmOperatorStatus select_similar_exec(bContext *C, wmOperator *op)
|
||||
grease_pencil,
|
||||
selection_domain,
|
||||
"opacity",
|
||||
handle_display,
|
||||
threshold,
|
||||
[](const float a, const float b) -> float { return math::distance(a, b); });
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user