Merge branch 'master' into blender2.8
[blender.git] / source / blender / blenkernel / intern / object_deform.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * ***** END GPL LICENSE BLOCK *****
19  */
20
21 /** \file blender/blenkernel/intern/object_deform.c
22  *  \ingroup bke
23  */
24
25 #include <stdlib.h>
26 #include <string.h>
27
28 #include "MEM_guardedalloc.h"
29
30 #include "BLT_translation.h"
31
32 #include "BLI_utildefines.h"
33 #include "BLI_ghash.h"
34 #include "BLI_listbase.h"
35 #include "BLI_string_utils.h"
36
37 #include "DNA_armature_types.h"
38 #include "DNA_cloth_types.h"
39 #include "DNA_curve_types.h"
40 #include "DNA_lattice_types.h"
41 #include "DNA_meshdata_types.h"
42 #include "DNA_mesh_types.h"
43 #include "DNA_modifier_types.h"
44 #include "DNA_object_types.h"
45 #include "DNA_object_force_types.h"
46 #include "DNA_particle_types.h"
47 #include "DNA_scene_types.h"
48
49 #include "BKE_action.h"
50 #include "BKE_deform.h"
51 #include "BKE_editmesh.h"
52 #include "BKE_object_deform.h"  /* own include */
53 #include "BKE_object.h"
54 #include "BKE_mesh.h"
55 #include "BKE_modifier.h"
56 #include "BKE_gpencil.h"
57
58 /** \name Misc helpers
59  * \{ */
60
61 static Lattice *object_defgroup_lattice_get(ID *id)
62 {
63         Lattice *lt = (Lattice *)id;
64         BLI_assert(GS(id->name) == ID_LT);
65         return (lt->editlatt) ? lt->editlatt->latt : lt;
66 }
67
68 /**
69  * Update users of vgroups from this object, according to given map.
70  *
71  * Use it when you remove or reorder vgroups in the object.
72  *
73  * \param map: an array mapping old indices to new indices.
74  */
75 void BKE_object_defgroup_remap_update_users(Object *ob, int *map)
76 {
77         ModifierData *md;
78         ParticleSystem *psys;
79         int a;
80
81         /* these cases don't use names to refer to vertex groups, so when
82          * they get removed the numbers get out of sync, this corrects that */
83
84         if (ob->soft) {
85                 ob->soft->vertgroup = map[ob->soft->vertgroup];
86         }
87
88         for (md = ob->modifiers.first; md; md = md->next) {
89                 if (md->type == eModifierType_Explode) {
90                         ExplodeModifierData *emd = (ExplodeModifierData *)md;
91                         emd->vgroup = map[emd->vgroup];
92                 }
93                 else if (md->type == eModifierType_Cloth) {
94                         ClothModifierData *clmd = (ClothModifierData *)md;
95                         ClothSimSettings *clsim = clmd->sim_parms;
96
97                         if (clsim) {
98                                 clsim->vgroup_mass = map[clsim->vgroup_mass];
99                                 clsim->vgroup_bend = map[clsim->vgroup_bend];
100                                 clsim->vgroup_struct = map[clsim->vgroup_struct];
101                         }
102                 }
103         }
104
105         for (psys = ob->particlesystem.first; psys; psys = psys->next) {
106                 for (a = 0; a < PSYS_TOT_VG; a++) {
107                         psys->vgroup[a] = map[psys->vgroup[a]];
108                 }
109         }
110 }
111 /** \} */
112
113
114 /** \name Group creation
115  * \{ */
116
117 /**
118  * Add a vgroup of given name to object. *Does not* handle MDeformVert data at all!
119  */
120 bDeformGroup *BKE_object_defgroup_add_name(Object *ob, const char *name)
121 {
122         bDeformGroup *defgroup;
123
124         if (!ob || !OB_TYPE_SUPPORT_VGROUP(ob->type))
125                 return NULL;
126
127         defgroup = BKE_defgroup_new(ob, name);
128
129         ob->actdef = BLI_listbase_count(&ob->defbase);
130
131         return defgroup;
132 }
133
134 /**
135  * Add a vgroup of default name to object. *Does not* handle MDeformVert data at all!
136  */
137 bDeformGroup *BKE_object_defgroup_add(Object *ob)
138 {
139         return BKE_object_defgroup_add_name(ob, DATA_("Group"));
140 }
141
142 /**
143  * Create MDeformVert data for given ID. Work in Object mode only.
144  */
145 MDeformVert *BKE_object_defgroup_data_create(ID *id)
146 {
147         if (GS(id->name) == ID_ME) {
148                 Mesh *me = (Mesh *)id;
149                 me->dvert = CustomData_add_layer(&me->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, me->totvert);
150                 return me->dvert;
151         }
152         else if (GS(id->name) == ID_LT) {
153                 Lattice *lt = (Lattice *)id;
154                 lt->dvert = MEM_callocN(sizeof(MDeformVert) * lt->pntsu * lt->pntsv * lt->pntsw, "lattice deformVert");
155                 return lt->dvert;
156         }
157
158         return NULL;
159 }
160 /** \} */
161
162
163 /** \name Group clearing
164  * \{ */
165
166 /**
167  * Remove all verts (or only selected ones) from given vgroup. Work in Object and Edit modes.
168  *
169  * \param use_selection: Only operate on selection.
170  * \return True if any vertex was removed, false otherwise.
171  */
172 bool BKE_object_defgroup_clear(Object *ob, bDeformGroup *dg, const bool use_selection)
173 {
174         MDeformVert *dv;
175         const int def_nr = BLI_findindex(&ob->defbase, dg);
176         bool changed = false;
177
178         if (ob->type == OB_MESH) {
179                 Mesh *me = ob->data;
180
181                 if (me->edit_btmesh) {
182                         BMEditMesh *em = me->edit_btmesh;
183                         const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT);
184
185                         if (cd_dvert_offset != -1) {
186                                 BMVert *eve;
187                                 BMIter iter;
188
189                                 BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
190                                         dv = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset);
191
192                                         if (dv && dv->dw && (!use_selection || BM_elem_flag_test(eve, BM_ELEM_SELECT))) {
193                                                 MDeformWeight *dw = defvert_find_index(dv, def_nr);
194                                                 defvert_remove_group(dv, dw); /* dw can be NULL */
195                                                 changed = true;
196                                         }
197                                 }
198                         }
199                 }
200                 else {
201                         if (me->dvert) {
202                                 MVert *mv;
203                                 int i;
204
205                                 mv = me->mvert;
206                                 dv = me->dvert;
207
208                                 for (i = 0; i < me->totvert; i++, mv++, dv++) {
209                                         if (dv->dw && (!use_selection || (mv->flag & SELECT))) {
210                                                 MDeformWeight *dw = defvert_find_index(dv, def_nr);
211                                                 defvert_remove_group(dv, dw);  /* dw can be NULL */
212                                                 changed = true;
213                                         }
214                                 }
215                         }
216                 }
217         }
218         else if (ob->type == OB_LATTICE) {
219                 Lattice *lt = object_defgroup_lattice_get((ID *)(ob->data));
220
221                 if (lt->dvert) {
222                         BPoint *bp;
223                         int i, tot = lt->pntsu * lt->pntsv * lt->pntsw;
224
225                         for (i = 0, bp = lt->def; i < tot; i++, bp++) {
226                                 if (!use_selection || (bp->f1 & SELECT)) {
227                                         MDeformWeight *dw;
228
229                                         dv = &lt->dvert[i];
230
231                                         dw = defvert_find_index(dv, def_nr);
232                                         defvert_remove_group(dv, dw);  /* dw can be NULL */
233                                         changed = true;
234                                 }
235                         }
236                 }
237         }
238
239         return changed;
240 }
241
242 /**
243  * Remove all verts (or only selected ones) from all vgroups. Work in Object and Edit modes.
244  *
245  * \param use_selection: Only operate on selection.
246  * \return True if any vertex was removed, false otherwise.
247  */
248 bool BKE_object_defgroup_clear_all(Object *ob, const bool use_selection)
249 {
250         bDeformGroup *dg;
251         bool changed = false;
252
253         for (dg = ob->defbase.first; dg; dg = dg->next) {
254                 if (BKE_object_defgroup_clear(ob, dg, use_selection)) {
255                         changed = true;
256                 }
257         }
258
259         return changed;
260 }
261 /** \} */
262
263
264 /** \name Group removal
265  * \{ */
266
267 static void object_defgroup_remove_update_users(Object *ob, const int idx)
268 {
269         int i, defbase_tot = BLI_listbase_count(&ob->defbase) + 1;
270         int *map = MEM_mallocN(sizeof(int) * defbase_tot, "vgroup del");
271
272         map[idx] = map[0] = 0;
273         for (i = 1; i < idx; i++) {
274                 map[i] = i;
275         }
276         for (i = idx + 1; i < defbase_tot; i++) {
277                 map[i] = i - 1;
278         }
279
280         BKE_object_defgroup_remap_update_users(ob, map);
281         MEM_freeN(map);
282 }
283
284 static void object_defgroup_remove_common(Object *ob, bDeformGroup *dg, const int def_nr)
285 {
286         object_defgroup_remove_update_users(ob, def_nr + 1);
287
288         /* Remove the group */
289         BLI_freelinkN(&ob->defbase, dg);
290
291         /* Update the active deform index if necessary */
292         if (ob->actdef > def_nr)
293                 ob->actdef--;
294
295         /* remove all dverts */
296         if (BLI_listbase_is_empty(&ob->defbase)) {
297                 if (ob->type == OB_MESH) {
298                         Mesh *me = ob->data;
299                         CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert);
300                         me->dvert = NULL;
301                 }
302                 else if (ob->type == OB_LATTICE) {
303                         Lattice *lt = object_defgroup_lattice_get((ID *)(ob->data));
304                         if (lt->dvert) {
305                                 MEM_freeN(lt->dvert);
306                                 lt->dvert = NULL;
307                         }
308                 }
309         }
310         else if (ob->actdef < 1) {  /* Keep a valid active index if we still have some vgroups. */
311                 ob->actdef = 1;
312         }
313 }
314
315 static void object_defgroup_remove_object_mode(Object *ob, bDeformGroup *dg)
316 {
317         MDeformVert *dvert_array = NULL;
318         int dvert_tot = 0;
319         const int def_nr = BLI_findindex(&ob->defbase, dg);
320
321         BLI_assert(def_nr != -1);
322
323         BKE_object_defgroup_array_get(ob->data, &dvert_array, &dvert_tot);
324
325         if (dvert_array) {
326                 int i, j;
327                 MDeformVert *dv;
328                 for (i = 0, dv = dvert_array; i < dvert_tot; i++, dv++) {
329                         MDeformWeight *dw;
330
331                         dw = defvert_find_index(dv, def_nr);
332                         defvert_remove_group(dv, dw); /* dw can be NULL */
333
334                         /* inline, make into a function if anything else needs to do this */
335                         for (j = 0; j < dv->totweight; j++) {
336                                 if (dv->dw[j].def_nr > def_nr) {
337                                         dv->dw[j].def_nr--;
338                                 }
339                         }
340                         /* done */
341                 }
342         }
343
344         object_defgroup_remove_common(ob, dg, def_nr);
345 }
346
347 static void object_defgroup_remove_edit_mode(Object *ob, bDeformGroup *dg)
348 {
349         int i;
350         const int def_nr = BLI_findindex(&ob->defbase, dg);
351
352         BLI_assert(def_nr != -1);
353
354         /* Make sure that no verts are using this group - if none were removed, we can skip next per-vert update. */
355         if (!BKE_object_defgroup_clear(ob, dg, false)) {
356                 /* Nothing to do. */
357         }
358         /* Else, make sure that any groups with higher indices are adjusted accordingly */
359         else if (ob->type == OB_MESH) {
360                 Mesh *me = ob->data;
361                 BMEditMesh *em = me->edit_btmesh;
362                 const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT);
363
364                 BMIter iter;
365                 BMVert *eve;
366                 MDeformVert *dvert;
367
368                 BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
369                         dvert = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset);
370
371                         if (dvert) {
372                                 for (i = 0; i < dvert->totweight; i++) {
373                                         if (dvert->dw[i].def_nr > def_nr) {
374                                                 dvert->dw[i].def_nr--;
375                                         }
376                                 }
377                         }
378                 }
379         }
380         else if (ob->type == OB_LATTICE) {
381                 Lattice *lt = ((Lattice *)(ob->data))->editlatt->latt;
382                 BPoint *bp;
383                 MDeformVert *dvert = lt->dvert;
384                 int a, tot;
385
386                 if (dvert) {
387                         tot = lt->pntsu * lt->pntsv * lt->pntsw;
388                         for (a = 0, bp = lt->def; a < tot; a++, bp++, dvert++) {
389                                 for (i = 0; i < dvert->totweight; i++) {
390                                         if (dvert->dw[i].def_nr > def_nr) {
391                                                 dvert->dw[i].def_nr--;
392                                         }
393                                 }
394                         }
395                 }
396         }
397
398         object_defgroup_remove_common(ob, dg, def_nr);
399 }
400
401 /**
402  * Remove given vgroup from object. Work in Object and Edit modes.
403  */
404 void BKE_object_defgroup_remove(Object *ob, bDeformGroup *defgroup)
405 {
406         if (ob->type == OB_GPENCIL) {
407                 BKE_gpencil_vgroup_remove(ob, defgroup);
408         }
409         else {
410                 if (BKE_object_is_in_editmode_vgroup(ob))
411                         object_defgroup_remove_edit_mode(ob, defgroup);
412                 else
413                         object_defgroup_remove_object_mode(ob, defgroup);
414
415                 BKE_object_batch_cache_dirty_tag(ob);
416         }
417 }
418
419 /**
420  * Remove all vgroups from object. Work in Object and Edit modes.
421  * When only_unlocked=true, locked vertex groups are not removed.
422  */
423 void BKE_object_defgroup_remove_all_ex(struct Object *ob, bool only_unlocked)
424 {
425         bDeformGroup *dg = (bDeformGroup *)ob->defbase.first;
426         const bool edit_mode = BKE_object_is_in_editmode_vgroup(ob);
427
428         if (dg) {
429                 while (dg) {
430                         bDeformGroup *next_dg = dg->next;
431
432                         if (!only_unlocked || (dg->flag & DG_LOCK_WEIGHT) == 0) {
433                                 if (edit_mode)
434                                         object_defgroup_remove_edit_mode(ob, dg);
435                                 else
436                                         object_defgroup_remove_object_mode(ob, dg);
437                         }
438
439                         dg = next_dg;
440                 }
441         }
442         else {  /* ob->defbase is empty... */
443                 /* remove all dverts */
444                 if (ob->type == OB_MESH) {
445                         Mesh *me = ob->data;
446                         CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert);
447                         me->dvert = NULL;
448                 }
449                 else if (ob->type == OB_LATTICE) {
450                         Lattice *lt = object_defgroup_lattice_get((ID *)(ob->data));
451                         if (lt->dvert) {
452                                 MEM_freeN(lt->dvert);
453                                 lt->dvert = NULL;
454                         }
455                 }
456                 /* Fix counters/indices */
457                 ob->actdef = 0;
458         }
459 }
460
461 /**
462  * Remove all vgroups from object. Work in Object and Edit modes.
463  */
464 void BKE_object_defgroup_remove_all(struct Object *ob)
465 {
466         BKE_object_defgroup_remove_all_ex(ob, false);
467 }
468
469 /**
470  * Compute mapping for vertex groups with matching name, -1 is used for no remapping.
471  * Returns null if no remapping is required.
472  * The returned array has to be freed.
473  */
474 int *BKE_object_defgroup_index_map_create(Object *ob_src, Object *ob_dst, int *r_map_len)
475 {
476         /* Build src to merged mapping of vgroup indices. */
477         if (BLI_listbase_is_empty(&ob_src->defbase) || BLI_listbase_is_empty(&ob_dst->defbase)) {
478                 *r_map_len = 0;
479                 return NULL;
480         }
481
482         bDeformGroup *dg_src;
483         *r_map_len = BLI_listbase_count(&ob_src->defbase);
484         int *vgroup_index_map = MEM_malloc_arrayN(*r_map_len, sizeof(*vgroup_index_map), "defgroup index map create");
485         bool is_vgroup_remap_needed = false;
486         int i;
487
488         for (dg_src = ob_src->defbase.first, i = 0; dg_src; dg_src = dg_src->next, i++) {
489                 vgroup_index_map[i] = defgroup_name_index(ob_dst, dg_src->name);
490                 is_vgroup_remap_needed = is_vgroup_remap_needed || (vgroup_index_map[i] != i);
491         }
492
493         if (!is_vgroup_remap_needed) {
494                 MEM_freeN(vgroup_index_map);
495                 vgroup_index_map = NULL;
496                 *r_map_len = 0;
497         }
498
499         return vgroup_index_map;
500 }
501
502 void BKE_object_defgroup_index_map_apply(MDeformVert *dvert, int dvert_len, const int *map, int map_len)
503 {
504         if (map == NULL || map_len == 0) {
505                 return;
506         }
507
508         MDeformVert *dv = dvert;
509         for (int i = 0; i < dvert_len; i++, dv++) {
510                 int totweight = dv->totweight;
511                 for (int j = 0; j < totweight; j++) {
512                         int def_nr = dv->dw[j].def_nr;
513                         if ((uint)def_nr < (uint)map_len && map[def_nr] != -1) {
514                                 dv->dw[j].def_nr = map[def_nr];
515                         }
516                         else {
517                                 totweight--;
518                                 dv->dw[j] = dv->dw[totweight];
519                                 j--;
520                         }
521                 }
522                 if (totweight != dv->totweight) {
523                         if (totweight) {
524                                 dv->dw = MEM_reallocN(dv->dw, sizeof(*dv->dw) * totweight);
525                         }
526                         else {
527                                 MEM_SAFE_FREE(dv->dw);
528                         }
529                         dv->totweight = totweight;
530                 }
531         }
532 }
533
534 /**
535  * Get MDeformVert vgroup data from given object. Should only be used in Object mode.
536  *
537  * \return True if the id type supports weights.
538  */
539 bool BKE_object_defgroup_array_get(ID *id, MDeformVert **dvert_arr, int *dvert_tot)
540 {
541         if (id) {
542                 switch (GS(id->name)) {
543                         case ID_ME:
544                         {
545                                 Mesh *me = (Mesh *)id;
546                                 *dvert_arr = me->dvert;
547                                 *dvert_tot = me->totvert;
548                                 return true;
549                         }
550                         case ID_LT:
551                         {
552                                 Lattice *lt = object_defgroup_lattice_get(id);
553                                 *dvert_arr = lt->dvert;
554                                 *dvert_tot = lt->pntsu * lt->pntsv * lt->pntsw;
555                                 return true;
556                         }
557                         default:
558                                 break;
559                 }
560         }
561
562         *dvert_arr = NULL;
563         *dvert_tot = 0;
564         return false;
565 }
566 /** \} */
567
568 /* --- functions for getting vgroup aligned maps --- */
569
570 /**
571  * gets the status of "flag" for each bDeformGroup
572  * in ob->defbase and returns an array containing them
573  */
574 bool *BKE_object_defgroup_lock_flags_get(Object *ob, const int defbase_tot)
575 {
576         bool is_locked = false;
577         int i;
578         //int defbase_tot = BLI_listbase_count(&ob->defbase);
579         bool *lock_flags = MEM_mallocN(defbase_tot * sizeof(bool), "defflags");
580         bDeformGroup *defgroup;
581
582         for (i = 0, defgroup = ob->defbase.first; i < defbase_tot && defgroup; defgroup = defgroup->next, i++) {
583                 lock_flags[i] = ((defgroup->flag & DG_LOCK_WEIGHT) != 0);
584                 is_locked |= lock_flags[i];
585         }
586         if (is_locked) {
587                 return lock_flags;
588         }
589
590         MEM_freeN(lock_flags);
591         return NULL;
592 }
593
594 bool *BKE_object_defgroup_validmap_get(Object *ob, const int defbase_tot)
595 {
596         bDeformGroup *dg;
597         ModifierData *md;
598         bool *defgroup_validmap;
599         GHash *gh;
600         int i, step1 = 1;
601         //int defbase_tot = BLI_listbase_count(&ob->defbase);
602         VirtualModifierData virtualModifierData;
603
604         if (BLI_listbase_is_empty(&ob->defbase)) {
605                 return NULL;
606         }
607
608         gh = BLI_ghash_str_new_ex(__func__, defbase_tot);
609
610         /* add all names to a hash table */
611         for (dg = ob->defbase.first; dg; dg = dg->next) {
612                 BLI_ghash_insert(gh, dg->name, NULL);
613         }
614
615         BLI_assert(BLI_ghash_len(gh) == defbase_tot);
616
617         /* now loop through the armature modifiers and identify deform bones */
618         for (md = ob->modifiers.first; md; md = !md->next && step1 ? (step1 = 0), modifiers_getVirtualModifierList(ob, &virtualModifierData) : md->next) {
619                 if (!(md->mode & (eModifierMode_Realtime | eModifierMode_Virtual)))
620                         continue;
621
622                 if (md->type == eModifierType_Armature) {
623                         ArmatureModifierData *amd = (ArmatureModifierData *) md;
624
625                         if (amd->object && amd->object->pose) {
626                                 bPose *pose = amd->object->pose;
627                                 bPoseChannel *chan;
628
629                                 for (chan = pose->chanbase.first; chan; chan = chan->next) {
630                                         void **val_p;
631                                         if (chan->bone->flag & BONE_NO_DEFORM)
632                                                 continue;
633
634                                         val_p = BLI_ghash_lookup_p(gh, chan->name);
635                                         if (val_p) {
636                                                 *val_p = POINTER_FROM_INT(1);
637                                         }
638                                 }
639                         }
640                 }
641         }
642
643         defgroup_validmap = MEM_mallocN(sizeof(*defgroup_validmap) * defbase_tot, "wpaint valid map");
644
645         /* add all names to a hash table */
646         for (dg = ob->defbase.first, i = 0; dg; dg = dg->next, i++) {
647                 defgroup_validmap[i] = (BLI_ghash_lookup(gh, dg->name) != NULL);
648         }
649
650         BLI_assert(i == BLI_ghash_len(gh));
651
652         BLI_ghash_free(gh, NULL, NULL);
653
654         return defgroup_validmap;
655 }
656
657 /* Returns total selected vgroups,
658  * wpi.defbase_sel is assumed malloc'd, all values are set */
659 bool *BKE_object_defgroup_selected_get(Object *ob, int defbase_tot, int *r_dg_flags_sel_tot)
660 {
661         bool *dg_selection = MEM_mallocN(defbase_tot * sizeof(bool), __func__);
662         bDeformGroup *defgroup;
663         unsigned int i;
664         Object *armob = BKE_object_pose_armature_get(ob);
665         (*r_dg_flags_sel_tot) = 0;
666
667         if (armob) {
668                 bPose *pose = armob->pose;
669                 for (i = 0, defgroup = ob->defbase.first; i < defbase_tot && defgroup; defgroup = defgroup->next, i++) {
670                         bPoseChannel *pchan = BKE_pose_channel_find_name(pose, defgroup->name);
671                         if (pchan && (pchan->bone->flag & BONE_SELECTED)) {
672                                 dg_selection[i] = true;
673                                 (*r_dg_flags_sel_tot) += 1;
674                         }
675                         else {
676                                 dg_selection[i] = false;
677                         }
678                 }
679         }
680         else {
681                 memset(dg_selection, false, sizeof(*dg_selection) * defbase_tot);
682         }
683
684         return dg_selection;
685 }
686
687 /* Marks mirror vgroups in output and counts them. Output and counter assumed to be already initialized.
688  * Designed to be usable after BKE_object_defgroup_selected_get to extend selection to mirror.
689  */
690 void BKE_object_defgroup_mirror_selection(
691         struct Object *ob, int defbase_tot, const bool *dg_selection,
692         bool *dg_flags_sel, int *r_dg_flags_sel_tot)
693 {
694         bDeformGroup *defgroup;
695         unsigned int i;
696         int i_mirr;
697
698         for (i = 0, defgroup = ob->defbase.first; i < defbase_tot && defgroup; defgroup = defgroup->next, i++) {
699                 if (dg_selection[i]) {
700                         char name_flip[MAXBONENAME];
701
702                         BLI_string_flip_side_name(name_flip, defgroup->name, false, sizeof(name_flip));
703                         i_mirr = STREQ(name_flip, defgroup->name) ? i : defgroup_name_index(ob, name_flip);
704
705                         if ((i_mirr >= 0 && i_mirr < defbase_tot) && (dg_flags_sel[i_mirr] == false)) {
706                                 dg_flags_sel[i_mirr] = true;
707                                 (*r_dg_flags_sel_tot) += 1;
708                         }
709                 }
710         }
711 }
712
713 /**
714  * Return the subset type of the Vertex Group Selection
715  */
716 bool *BKE_object_defgroup_subset_from_select_type(
717         Object *ob, eVGroupSelect subset_type, int *r_defgroup_tot, int *r_subset_count)
718 {
719         bool *defgroup_validmap = NULL;
720         *r_defgroup_tot = BLI_listbase_count(&ob->defbase);
721
722         switch (subset_type) {
723                 case WT_VGROUP_ACTIVE:
724                 {
725                         const int def_nr_active = ob->actdef - 1;
726                         defgroup_validmap = MEM_mallocN(*r_defgroup_tot * sizeof(*defgroup_validmap), __func__);
727                         memset(defgroup_validmap, false, *r_defgroup_tot * sizeof(*defgroup_validmap));
728                         if ((def_nr_active >= 0) && (def_nr_active < *r_defgroup_tot)) {
729                                 *r_subset_count = 1;
730                                 defgroup_validmap[def_nr_active] = true;
731                         }
732                         else {
733                                 *r_subset_count = 0;
734                         }
735                         break;
736                 }
737                 case WT_VGROUP_BONE_SELECT:
738                 {
739                         defgroup_validmap = BKE_object_defgroup_selected_get(ob, *r_defgroup_tot, r_subset_count);
740                         break;
741                 }
742                 case WT_VGROUP_BONE_DEFORM:
743                 {
744                         int i;
745                         defgroup_validmap = BKE_object_defgroup_validmap_get(ob, *r_defgroup_tot);
746                         *r_subset_count = 0;
747                         for (i = 0; i < *r_defgroup_tot; i++) {
748                                 if (defgroup_validmap[i] == true) {
749                                         *r_subset_count += 1;
750                                 }
751                         }
752                         break;
753                 }
754                 case WT_VGROUP_BONE_DEFORM_OFF:
755                 {
756                         int i;
757                         defgroup_validmap = BKE_object_defgroup_validmap_get(ob, *r_defgroup_tot);
758                         *r_subset_count = 0;
759                         for (i = 0; i < *r_defgroup_tot; i++) {
760                                 defgroup_validmap[i] = !defgroup_validmap[i];
761                                 if (defgroup_validmap[i] == true) {
762                                         *r_subset_count += 1;
763                                 }
764                         }
765                         break;
766                 }
767                 case WT_VGROUP_ALL:
768                 default:
769                 {
770                         defgroup_validmap = MEM_mallocN(*r_defgroup_tot * sizeof(*defgroup_validmap), __func__);
771                         memset(defgroup_validmap, true, *r_defgroup_tot * sizeof(*defgroup_validmap));
772                         *r_subset_count = *r_defgroup_tot;
773                         break;
774                 }
775         }
776
777         return defgroup_validmap;
778 }
779
780 /**
781  * store indices from the defgroup_validmap (faster lookups in some cases)
782  */
783 void BKE_object_defgroup_subset_to_index_array(
784         const bool *defgroup_validmap, const int defgroup_tot, int *r_defgroup_subset_map)
785 {
786         int i, j = 0;
787         for (i = 0; i < defgroup_tot; i++) {
788                 if (defgroup_validmap[i]) {
789                         r_defgroup_subset_map[j++] = i;
790                 }
791         }
792 }