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 = <->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