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