From 40162873e0e2edba561c7cff78b1ebb35e0d730c Mon Sep 17 00:00:00 2001 From: Pratik Borhade Date: Wed, 6 Nov 2024 04:16:48 +0100 Subject: [PATCH] Fix #129632: GPv3: Vgroup operation edits drawings from all keyframes Verge groups operations such as assign/remove/select/deselect from data properties tab edits all drawings instead of visible drawings at current frame. Now fixed with `retrieve_editable_drawings`. For remove/remove_from operator, separate PR is created: !129890 Pull Request: https://projects.blender.org/blender/blender/pulls/129789 --- .../BKE_grease_pencil_vertex_groups.hh | 6 +- .../intern/grease_pencil_vertex_groups.cc | 170 +++++++++--------- .../blender/editors/object/object_vgroup.cc | 36 +++- 3 files changed, 115 insertions(+), 97 deletions(-) diff --git a/source/blender/blenkernel/BKE_grease_pencil_vertex_groups.hh b/source/blender/blenkernel/BKE_grease_pencil_vertex_groups.hh index e233829460a..5aef5a50823 100644 --- a/source/blender/blenkernel/BKE_grease_pencil_vertex_groups.hh +++ b/source/blender/blenkernel/BKE_grease_pencil_vertex_groups.hh @@ -22,7 +22,10 @@ void validate_drawing_vertex_groups(GreasePencil &grease_pencil); int ensure_vertex_group(const StringRef name, ListBase &vertex_group_names); /** Assign selected vertices to the vertex group. */ -void assign_to_vertex_group(GreasePencil &grease_pencil, StringRef name, float weight); +void assign_to_vertex_group(GreasePencil &grease_pencil, + Drawing &drawing, + StringRef name, + float weight); void assign_to_vertex_group_from_mask(CurvesGeometry &curves, const IndexMask &mask, @@ -40,6 +43,7 @@ void clear_vertex_groups(GreasePencil &grease_pencil); /** Select or deselect vertices assigned to this group. */ void select_from_group(GreasePencil &grease_pencil, + Drawing &drawing, const AttrDomain selection_domain, StringRef name, bool select); diff --git a/source/blender/blenkernel/intern/grease_pencil_vertex_groups.cc b/source/blender/blenkernel/intern/grease_pencil_vertex_groups.cc index 611bb35464d..7ef6fa41aa4 100644 --- a/source/blender/blenkernel/intern/grease_pencil_vertex_groups.cc +++ b/source/blender/blenkernel/intern/grease_pencil_vertex_groups.cc @@ -95,40 +95,38 @@ void assign_to_vertex_group_from_mask(bke::CurvesGeometry &curves, }); } -void assign_to_vertex_group(GreasePencil &grease_pencil, const StringRef name, const float weight) +void assign_to_vertex_group(GreasePencil &grease_pencil, + Drawing &drawing, + const StringRef name, + const float weight) { - for (GreasePencilDrawingBase *base : grease_pencil.drawings()) { - if (base->type != GP_DRAWING) { - continue; - } - Drawing &drawing = reinterpret_cast(base)->wrap(); - bke::CurvesGeometry &curves = drawing.strokes_for_write(); - ListBase &vertex_group_names = curves.vertex_group_names; - const bke::AttributeAccessor attributes = curves.attributes(); - const VArray selection = *attributes.lookup_or_default( - ".selection", bke::AttrDomain::Point, true); + bke::CurvesGeometry &curves = drawing.strokes_for_write(); + ListBase &vertex_group_names = curves.vertex_group_names; - /* Look for existing group, otherwise lazy-initialize if any vertex is selected. */ - int def_nr = BKE_defgroup_name_index(&vertex_group_names, name); + const bke::AttributeAccessor attributes = curves.attributes(); + const VArray selection = *attributes.lookup_or_default( + ".selection", bke::AttrDomain::Point, true); - const MutableSpan dverts = curves.deform_verts_for_write(); - for (const int i : dverts.index_range()) { - if (selection[i]) { - /* Lazily add the vertex group if any vertex is selected. */ - if (def_nr < 0) { - bDeformGroup *defgroup = MEM_cnew(__func__); - name.copy(defgroup->name); + /* Look for existing group, otherwise lazy-initialize if any vertex is selected. */ + int def_nr = BKE_defgroup_name_index(&vertex_group_names, name); - BLI_addtail(&vertex_group_names, defgroup); - def_nr = BLI_listbase_count(&vertex_group_names) - 1; - BLI_assert(def_nr >= 0); - } + const MutableSpan dverts = curves.deform_verts_for_write(); + for (const int i : dverts.index_range()) { + if (selection[i]) { + /* Lazily add the vertex group if any vertex is selected. */ + if (def_nr < 0) { + bDeformGroup *defgroup = MEM_cnew(__func__); + name.copy(defgroup->name); - MDeformWeight *dw = BKE_defvert_ensure_index(&dverts[i], def_nr); - if (dw) { - dw->weight = weight; - } + BLI_addtail(&vertex_group_names, defgroup); + def_nr = BLI_listbase_count(&vertex_group_names) - 1; + BLI_assert(def_nr >= 0); + } + + MDeformWeight *dw = BKE_defvert_ensure_index(&dverts[i], def_nr); + if (dw) { + dw->weight = weight; } } } @@ -193,73 +191,69 @@ void clear_vertex_groups(GreasePencil &grease_pencil) } void select_from_group(GreasePencil &grease_pencil, + Drawing &drawing, const AttrDomain selection_domain, const StringRef name, const bool select) { - for (GreasePencilDrawingBase *base : grease_pencil.drawings()) { - if (base->type != GP_DRAWING) { - continue; - } - Drawing &drawing = reinterpret_cast(base)->wrap(); - 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. */ - continue; - } + bke::CurvesGeometry &curves = drawing.strokes_for_write(); + ListBase &vertex_group_names = curves.vertex_group_names; - const Span dverts = curves.deform_verts_for_write(); - if (dverts.is_empty()) { - continue; - } - - MutableAttributeAccessor attributes = curves.attributes_for_write(); - const int num_elements = attributes.domain_size(selection_domain); - SpanAttributeWriter selection = attributes.lookup_or_add_for_write_span( - ".selection", - selection_domain, - bke::AttributeInitVArray(VArray::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 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(); + 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 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 selection = attributes.lookup_or_add_for_write_span( + ".selection", + selection_domain, + bke::AttributeInitVArray(VArray::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 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(); } /** \} */ diff --git a/source/blender/editors/object/object_vgroup.cc b/source/blender/editors/object/object_vgroup.cc index e14ce85c20c..193fcff3094 100644 --- a/source/blender/editors/object/object_vgroup.cc +++ b/source/blender/editors/object/object_vgroup.cc @@ -1006,7 +1006,10 @@ void vgroup_select_by_name(Object *ob, const char *name) * \{ */ /* only in editmode */ -static void vgroup_select_verts(const ToolSettings &tool_settings, Object *ob, int select) +static void vgroup_select_verts(const ToolSettings &tool_settings, + Object *ob, + Scene &scene, + int select) { const int def_nr = BKE_object_defgroup_active_index_get(ob) - 1; @@ -1098,8 +1101,14 @@ static void vgroup_select_verts(const ToolSettings &tool_settings, Object *ob, i const bke::AttrDomain selection_domain = ED_grease_pencil_edit_selection_domain_get( &tool_settings); GreasePencil *grease_pencil = static_cast(ob->data); - bke::greasepencil::select_from_group( - *grease_pencil, selection_domain, def_group->name, bool(select)); + { + using namespace ed::greasepencil; + Vector drawings = retrieve_editable_drawings(scene, *grease_pencil); + for (MutableDrawingInfo info : drawings) { + bke::greasepencil::select_from_group( + *grease_pencil, info.drawing, selection_domain, def_group->name, bool(select)); + } + } DEG_id_tag_update(&grease_pencil->id, ID_RECALC_GEOMETRY); } } @@ -2218,7 +2227,7 @@ static void vgroup_delete_active(Object *ob) } /* only in editmode */ -static void vgroup_assign_verts(Object *ob, const float weight) +static void vgroup_assign_verts(Object *ob, Scene &scene, const float weight) { const int def_nr = BKE_object_defgroup_active_index_get(ob) - 1; @@ -2303,7 +2312,15 @@ static void vgroup_assign_verts(Object *ob, const float weight) GreasePencil *grease_pencil = static_cast(ob->data); const bDeformGroup *defgroup = static_cast( BLI_findlink(BKE_object_defgroup_list(ob), def_nr)); - bke::greasepencil::assign_to_vertex_group(*grease_pencil, defgroup->name, weight); + + { + using namespace ed::greasepencil; + Vector drawings = retrieve_editable_drawings(scene, *grease_pencil); + for (MutableDrawingInfo info : drawings) { + bke::greasepencil::assign_to_vertex_group( + *grease_pencil, info.drawing, defgroup->name, weight); + } + } } } @@ -2566,8 +2583,9 @@ static int vertex_group_assign_exec(bContext *C, wmOperator * /*op*/) { ToolSettings *ts = CTX_data_tool_settings(C); Object *ob = context_object(C); + Scene &scene = *CTX_data_scene(C); - vgroup_assign_verts(ob, ts->vgroup_weight); + vgroup_assign_verts(ob, scene, ts->vgroup_weight); DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); @@ -2697,12 +2715,13 @@ static int vertex_group_select_exec(bContext *C, wmOperator * /*op*/) { const ToolSettings &tool_settings = *CTX_data_scene(C)->toolsettings; Object *ob = context_object(C); + Scene &scene = *CTX_data_scene(C); if (!ob || !ID_IS_EDITABLE(ob) || ID_IS_OVERRIDE_LIBRARY(ob)) { return OPERATOR_CANCELLED; } - vgroup_select_verts(tool_settings, ob, 1); + vgroup_select_verts(tool_settings, ob, scene, 1); DEG_id_tag_update(static_cast(ob->data), ID_RECALC_SYNC_TO_EVAL | ID_RECALC_SELECT); WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob->data); @@ -2734,8 +2753,9 @@ static int vertex_group_deselect_exec(bContext *C, wmOperator * /*op*/) { const ToolSettings &tool_settings = *CTX_data_scene(C)->toolsettings; Object *ob = context_object(C); + Scene &scene = *CTX_data_scene(C); - vgroup_select_verts(tool_settings, ob, 0); + vgroup_select_verts(tool_settings, ob, scene, 0); DEG_id_tag_update(static_cast(ob->data), ID_RECALC_SYNC_TO_EVAL | ID_RECALC_SELECT); WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob->data);