Blender V5.0
grease_pencil_vertex_groups.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
10#include "DNA_object_types.h"
11
12#include "BLI_listbase.h"
13#include "BLI_set.hh"
14
15#include "BKE_curves.hh"
16#include "BKE_deform.hh"
17#include "BKE_grease_pencil.hh"
19
21
22/* ------------------------------------------------------------------- */
25
27{
28 Set<std::string> valid_names;
29 LISTBASE_FOREACH (const bDeformGroup *, defgroup, &grease_pencil.vertex_group_names) {
30 valid_names.add_new(defgroup->name);
31 }
32
33 for (GreasePencilDrawingBase *base : grease_pencil.drawings()) {
34 if (base->type != GP_DRAWING) {
35 continue;
36 }
37 Drawing &drawing = reinterpret_cast<GreasePencilDrawing *>(base)->wrap();
38
39 /* Remove unknown vertex groups. */
41 int defgroup_index = 0;
42 LISTBASE_FOREACH_MUTABLE (bDeformGroup *, defgroup, &curves.vertex_group_names) {
43 if (!valid_names.contains(defgroup->name)) {
44 remove_defgroup_index(curves.deform_verts_for_write(), defgroup_index);
45
46 BLI_remlink(&curves.vertex_group_names, defgroup);
47 MEM_SAFE_FREE(defgroup);
48 }
49
50 ++defgroup_index;
51 }
52 }
53}
54
55int ensure_vertex_group(const StringRef name, ListBase &vertex_group_names)
56{
57 int def_nr = BKE_defgroup_name_index(&vertex_group_names, name);
58 if (def_nr < 0) {
59 bDeformGroup *defgroup = MEM_callocN<bDeformGroup>(__func__);
60 name.copy_utf8_truncated(defgroup->name);
61 BLI_addtail(&vertex_group_names, defgroup);
62 def_nr = BLI_listbase_count(&vertex_group_names) - 1;
63 BLI_assert(def_nr >= 0);
64 }
65 return def_nr;
66}
67
69 const IndexMask &mask,
70 const StringRef name,
71 const float weight)
72{
73 if (mask.is_empty()) {
74 return;
75 }
76
77 ListBase &vertex_group_names = curves.vertex_group_names;
78 /* Look for existing group, otherwise lazy-initialize if any vertex is selected. */
79 int def_nr = BKE_defgroup_name_index(&vertex_group_names, name);
80
81 /* Lazily add the vertex group if any vertex is selected. */
82 if (def_nr < 0) {
83 bDeformGroup *defgroup = MEM_callocN<bDeformGroup>(__func__);
84 name.copy_utf8_truncated(defgroup->name);
85 BLI_addtail(&vertex_group_names, defgroup);
86 def_nr = BLI_listbase_count(&vertex_group_names) - 1;
87 BLI_assert(def_nr >= 0);
88 }
89
90 const MutableSpan<MDeformVert> dverts = curves.deform_verts_for_write();
91 mask.foreach_index([&](const int point_i) {
92 if (MDeformWeight *dw = BKE_defvert_ensure_index(&dverts[point_i], def_nr)) {
93 dw->weight = weight;
94 }
95 });
96}
97
98void assign_to_vertex_group(Drawing &drawing, const StringRef name, const float weight)
99{
100
102 ListBase &vertex_group_names = curves.vertex_group_names;
103
104 const bke::AttributeAccessor attributes = curves.attributes();
105 const VArray<bool> selection = *attributes.lookup_or_default<bool>(
106 ".selection", bke::AttrDomain::Point, true);
107
108 /* Look for existing group, otherwise lazy-initialize if any vertex is selected. */
109 int def_nr = BKE_defgroup_name_index(&vertex_group_names, name);
110
111 const MutableSpan<MDeformVert> dverts = curves.deform_verts_for_write();
112 for (const int i : dverts.index_range()) {
113 if (selection[i]) {
114 /* Lazily add the vertex group if any vertex is selected. */
115 if (def_nr < 0) {
116 bDeformGroup *defgroup = MEM_callocN<bDeformGroup>(__func__);
117 name.copy_utf8_truncated(defgroup->name);
118
119 BLI_addtail(&vertex_group_names, defgroup);
120 def_nr = BLI_listbase_count(&vertex_group_names) - 1;
121 BLI_assert(def_nr >= 0);
122 }
123
124 MDeformWeight *dw = BKE_defvert_ensure_index(&dverts[i], def_nr);
125 if (dw) {
126 dw->weight = weight;
127 }
128 }
129 }
130}
131
132bool remove_from_vertex_group(Drawing &drawing, const StringRef name, const bool use_selection)
133{
134 bool changed = false;
136 ListBase &vertex_group_names = curves.vertex_group_names;
137
138 const int def_nr = BKE_defgroup_name_index(&vertex_group_names, name);
139 if (def_nr < 0) {
140 /* No vertices assigned to the group in this drawing. */
141 return false;
142 }
143
144 const MutableSpan<MDeformVert> dverts = curves.deform_verts_for_write();
145 const bke::AttributeAccessor attributes = curves.attributes();
146 const VArray<bool> selection = *attributes.lookup_or_default<bool>(
147 ".selection", bke::AttrDomain::Point, true);
148 for (const int i : dverts.index_range()) {
149 if (!use_selection || selection[i]) {
150 MDeformVert *dv = &dverts[i];
151 MDeformWeight *dw = BKE_defvert_find_index(dv, def_nr);
153 changed = true;
154 }
155 }
156 return changed;
157}
158
160{
161 for (GreasePencilDrawingBase *base : grease_pencil.drawings()) {
162 if (base->type != GP_DRAWING) {
163 continue;
164 }
165 Drawing &drawing = reinterpret_cast<GreasePencilDrawing *>(base)->wrap();
167
168 for (MDeformVert &dvert : curves.deform_verts_for_write()) {
169 BKE_defvert_clear(&dvert);
170 }
171 }
172}
173
175
176} // namespace blender::bke::greasepencil
Low-level operations for curves.
support for deformation groups and hooks.
int BKE_defgroup_name_index(const ListBase *defbase, blender::StringRef name)
Definition deform.cc:540
MDeformWeight * BKE_defvert_ensure_index(MDeformVert *dv, int defgroup)
Definition deform.cc:825
MDeformWeight * BKE_defvert_find_index(const MDeformVert *dv, int defgroup)
Definition deform.cc:806
void BKE_defvert_clear(MDeformVert *dvert)
Definition deform.cc:913
void BKE_defvert_remove_group(MDeformVert *dvert, MDeformWeight *dw)
Definition deform.cc:880
Low-level operations for grease pencil.
Utility functions for vertex groups in grease pencil objects.
#define BLI_assert(a)
Definition BLI_assert.h:46
#define LISTBASE_FOREACH(type, var, list)
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:111
void BLI_remlink(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:131
int BLI_listbase_count(const ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:524
Object is a sort of wrapper for general info.
#define MEM_SAFE_FREE(v)
constexpr IndexRange index_range() const
Definition BLI_span.hh:670
bool contains(const Key &key) const
Definition BLI_set.hh:310
void add_new(const Key &key)
Definition BLI_set.hh:233
GAttributeReader lookup_or_default(StringRef attribute_id, AttrDomain domain, AttrType data_type, const void *default_value=nullptr) const
bke::CurvesGeometry & strokes_for_write()
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
void clear_vertex_groups(GreasePencil &grease_pencil)
bool remove_from_vertex_group(Drawing &drawing, StringRef name, bool use_selection)
int ensure_vertex_group(StringRef name, ListBase &vertex_group_names)
void assign_to_vertex_group(Drawing &drawing, StringRef name, float weight)
void assign_to_vertex_group_from_mask(CurvesGeometry &curves, const IndexMask &mask, StringRef name, float weight)
void validate_drawing_vertex_groups(GreasePencil &grease_pencil)
void remove_defgroup_index(MutableSpan< MDeformVert > dverts, int defgroup_index)
Definition deform.cc:1753
float wrap(float value, float max, float min)
Definition node_math.h:103
const char * name
i
Definition text_draw.cc:230