Fix: Grease Pencil: Use ensure_selection_attribute in vgroup_select_verts

This was implemented in the kernel but it shouldn't have been.
Since the function operates at the editor level and doesn't
only work at the low-level, it should be in the `object_vgroup.cc` file
in the `editor` context.

This also means that we can use `ensure_selection_attribute` which
fixes a crash when the selection attribute is on the wrong domain.

Pull Request: https://projects.blender.org/blender/blender/pulls/134060
This commit is contained in:
Falk David
2025-02-07 12:22:29 +01:00
committed by Falk David
parent e58b6a3279
commit 8c01a59411
3 changed files with 72 additions and 83 deletions

View File

@@ -38,10 +38,4 @@ bool remove_from_vertex_group(Drawing &drawing, StringRef name, bool use_selecti
/** Remove vertices from all vertex groups. */
void clear_vertex_groups(GreasePencil &grease_pencil);
/** Select or deselect vertices assigned to this group. */
void select_from_group(Drawing &drawing,
const AttrDomain selection_domain,
StringRef name,
bool select);
} // namespace blender::bke::greasepencil

View File

@@ -171,71 +171,6 @@ void clear_vertex_groups(GreasePencil &grease_pencil)
}
}
void select_from_group(Drawing &drawing,
const AttrDomain selection_domain,
const StringRef name,
const bool select)
{
bke::CurvesGeometry &curves = drawing.strokes_for_write();
ListBase &vertex_group_names = curves.vertex_group_names;
const int def_nr = BKE_defgroup_name_index(&vertex_group_names, name);
if (def_nr < 0) {
/* No vertices assigned to the group in this drawing. */
return;
}
const Span<MDeformVert> dverts = curves.deform_verts_for_write();
if (dverts.is_empty()) {
return;
}
MutableAttributeAccessor attributes = curves.attributes_for_write();
const int num_elements = attributes.domain_size(selection_domain);
SpanAttributeWriter<bool> selection = attributes.lookup_or_add_for_write_span<bool>(
".selection",
selection_domain,
bke::AttributeInitVArray(VArray<bool>::ForSingle(true, num_elements)));
switch (selection_domain) {
case AttrDomain::Point:
threading::parallel_for(curves.points_range(), 4096, [&](const IndexRange range) {
for (const int point_i : range) {
if (BKE_defvert_find_index(&dverts[point_i], def_nr)) {
selection.span[point_i] = select;
}
}
});
break;
case AttrDomain::Curve: {
const OffsetIndices<int> points_by_curve = curves.points_by_curve();
threading::parallel_for(curves.curves_range(), 1024, [&](const IndexRange range) {
for (const int curve_i : range) {
const IndexRange points = points_by_curve[curve_i];
bool any_point_in_group = false;
for (const int point_i : points) {
if (BKE_defvert_find_index(&dverts[point_i], def_nr)) {
any_point_in_group = true;
break;
}
}
if (any_point_in_group) {
selection.span[curve_i] = select;
}
}
});
break;
}
default:
BLI_assert_unreachable();
break;
}
selection.finish();
}
/** \} */
} // namespace blender::bke::greasepencil

View File

@@ -29,6 +29,7 @@
#include "BKE_attribute.hh"
#include "BKE_context.hh"
#include "BKE_curves.hh"
#include "BKE_customdata.hh"
#include "BKE_deform.hh"
#include "BKE_editmesh.hh"
@@ -54,6 +55,7 @@
#include "WM_api.hh"
#include "WM_types.hh"
#include "ED_curves.hh"
#include "ED_grease_pencil.hh"
#include "ED_mesh.hh"
#include "ED_object.hh"
@@ -1001,6 +1003,75 @@ void vgroup_select_by_name(Object *ob, const char *name)
/** \name Operator Function Implementations
* \{ */
static void vgroup_grease_pencil_select_verts(const Scene &scene,
const ToolSettings &tool_settings,
const bDeformGroup *def_group,
const bool select,
Object &object)
{
using namespace bke;
using namespace ed::greasepencil;
const bke::AttrDomain selection_domain = ED_grease_pencil_edit_selection_domain_get(
&tool_settings);
GreasePencil *grease_pencil = static_cast<GreasePencil *>(object.data);
Vector<MutableDrawingInfo> drawings = retrieve_editable_drawings(scene, *grease_pencil);
for (MutableDrawingInfo &info : drawings) {
bke::CurvesGeometry &curves = info.drawing.strokes_for_write();
ListBase &vertex_group_names = curves.vertex_group_names;
const int def_nr = BKE_defgroup_name_index(&vertex_group_names, def_group->name);
if (def_nr < 0) {
/* No vertices assigned to the group in this drawing. */
return;
}
const Span<MDeformVert> dverts = curves.deform_verts();
if (dverts.is_empty()) {
return;
}
GSpanAttributeWriter selection = ed::curves::ensure_selection_attribute(
curves, selection_domain, CD_PROP_BOOL);
switch (selection_domain) {
case AttrDomain::Point:
threading::parallel_for(curves.points_range(), 4096, [&](const IndexRange range) {
for (const int point_i : range) {
if (BKE_defvert_find_index(&dverts[point_i], def_nr)) {
selection.span.typed<bool>()[point_i] = select;
}
}
});
break;
case AttrDomain::Curve: {
const OffsetIndices<int> points_by_curve = curves.points_by_curve();
threading::parallel_for(curves.curves_range(), 1024, [&](const IndexRange range) {
for (const int curve_i : range) {
const IndexRange points = points_by_curve[curve_i];
bool any_point_in_group = false;
for (const int point_i : points) {
if (BKE_defvert_find_index(&dverts[point_i], def_nr)) {
any_point_in_group = true;
break;
}
}
if (any_point_in_group) {
selection.span.typed<bool>()[curve_i] = select;
}
}
});
break;
}
default:
BLI_assert_unreachable();
break;
}
selection.finish();
}
DEG_id_tag_update(&grease_pencil->id, ID_RECALC_GEOMETRY);
}
/* only in editmode */
static void vgroup_select_verts(const ToolSettings &tool_settings,
Object *ob,
@@ -1094,18 +1165,7 @@ static void vgroup_select_verts(const ToolSettings &tool_settings,
}
}
else if (ob->type == OB_GREASE_PENCIL) {
const bke::AttrDomain selection_domain = ED_grease_pencil_edit_selection_domain_get(
&tool_settings);
GreasePencil *grease_pencil = static_cast<GreasePencil *>(ob->data);
{
using namespace ed::greasepencil;
Vector<MutableDrawingInfo> drawings = retrieve_editable_drawings(scene, *grease_pencil);
for (MutableDrawingInfo info : drawings) {
bke::greasepencil::select_from_group(
info.drawing, selection_domain, def_group->name, bool(select));
}
}
DEG_id_tag_update(&grease_pencil->id, ID_RECALC_GEOMETRY);
vgroup_grease_pencil_select_verts(scene, tool_settings, def_group, select, *ob);
}
}