Blender  V3.3
object_deform.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
7 #include <stdlib.h>
8 #include <string.h>
9 
10 #include "MEM_guardedalloc.h"
11 
12 #include "BLT_translation.h"
13 
14 #include "BLI_ghash.h"
15 #include "BLI_listbase.h"
16 #include "BLI_string_utils.h"
17 #include "BLI_utildefines.h"
18 
19 #include "DNA_armature_types.h"
20 #include "DNA_cloth_types.h"
21 #include "DNA_curve_types.h"
22 #include "DNA_gpencil_types.h"
23 #include "DNA_lattice_types.h"
24 #include "DNA_mesh_types.h"
25 #include "DNA_meshdata_types.h"
26 #include "DNA_modifier_types.h"
27 #include "DNA_object_force_types.h"
28 #include "DNA_object_types.h"
29 #include "DNA_particle_types.h"
30 #include "DNA_scene_types.h"
31 
32 #include "BKE_action.h"
33 #include "BKE_deform.h"
34 #include "BKE_editmesh.h"
35 #include "BKE_gpencil.h"
36 #include "BKE_mesh.h"
37 #include "BKE_modifier.h"
38 #include "BKE_object.h"
39 #include "BKE_object_deform.h" /* own include */
40 
41 /* -------------------------------------------------------------------- */
46 {
47  Lattice *lt = (Lattice *)id;
48  BLI_assert(GS(id->name) == ID_LT);
49  return (lt->editlatt) ? lt->editlatt->latt : lt;
50 }
51 
53 {
54  ModifierData *md;
55  ParticleSystem *psys;
56  int a;
57 
58  /* these cases don't use names to refer to vertex groups, so when
59  * they get removed the numbers get out of sync, this corrects that */
60 
61  if (ob->soft) {
62  ob->soft->vertgroup = map[ob->soft->vertgroup];
63  }
64 
65  for (md = ob->modifiers.first; md; md = md->next) {
66  if (md->type == eModifierType_Explode) {
68  emd->vgroup = map[emd->vgroup];
69  }
70  else if (md->type == eModifierType_Cloth) {
72  ClothSimSettings *clsim = clmd->sim_parms;
73 
74  if (clsim) {
75  clsim->vgroup_mass = map[clsim->vgroup_mass];
76  clsim->vgroup_bend = map[clsim->vgroup_bend];
77  clsim->vgroup_struct = map[clsim->vgroup_struct];
78  }
79  }
80  }
81 
82  for (psys = ob->particlesystem.first; psys; psys = psys->next) {
83  for (a = 0; a < PSYS_TOT_VG; a++) {
84  psys->vgroup[a] = map[psys->vgroup[a]];
85  }
86  }
87 }
88 
91 /* -------------------------------------------------------------------- */
96 {
97  bDeformGroup *defgroup;
98 
99  if (!ob || !OB_TYPE_SUPPORT_VGROUP(ob->type)) {
100  return NULL;
101  }
102 
103  defgroup = BKE_object_defgroup_new(ob, name);
105 
106  return defgroup;
107 }
108 
110 {
111  return BKE_object_defgroup_add_name(ob, DATA_("Group"));
112 }
113 
115 {
116  if (GS(id->name) == ID_ME) {
117  Mesh *me = (Mesh *)id;
119  return me->dvert;
120  }
121  if (GS(id->name) == ID_LT) {
122  Lattice *lt = (Lattice *)id;
123  lt->dvert = MEM_callocN(sizeof(MDeformVert) * lt->pntsu * lt->pntsv * lt->pntsw,
124  "lattice deformVert");
125  return lt->dvert;
126  }
127 
128  return NULL;
129 }
130 
133 /* -------------------------------------------------------------------- */
137 bool BKE_object_defgroup_clear(Object *ob, bDeformGroup *dg, const bool use_selection)
138 {
139  MDeformVert *dv;
140  const ListBase *defbase = BKE_object_defgroup_list(ob);
141  const int def_nr = BLI_findindex(defbase, dg);
142  bool changed = false;
143 
144  if (ob->type == OB_MESH) {
145  Mesh *me = ob->data;
146 
147  if (me->edit_mesh) {
148  BMEditMesh *em = me->edit_mesh;
149  const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT);
150 
151  if (cd_dvert_offset != -1) {
152  BMVert *eve;
153  BMIter iter;
154 
155  BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
156  dv = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset);
157 
158  if (dv && dv->dw && (!use_selection || BM_elem_flag_test(eve, BM_ELEM_SELECT))) {
159  MDeformWeight *dw = BKE_defvert_find_index(dv, def_nr);
160  BKE_defvert_remove_group(dv, dw); /* dw can be NULL */
161  changed = true;
162  }
163  }
164  }
165  }
166  else {
167  if (me->dvert) {
168  MVert *mv;
169  int i;
170 
171  mv = me->mvert;
172  dv = me->dvert;
173 
174  for (i = 0; i < me->totvert; i++, mv++, dv++) {
175  if (dv->dw && (!use_selection || (mv->flag & SELECT))) {
176  MDeformWeight *dw = BKE_defvert_find_index(dv, def_nr);
177  BKE_defvert_remove_group(dv, dw); /* dw can be NULL */
178  changed = true;
179  }
180  }
181  }
182  }
183  }
184  else if (ob->type == OB_LATTICE) {
185  Lattice *lt = object_defgroup_lattice_get((ID *)(ob->data));
186 
187  if (lt->dvert) {
188  BPoint *bp;
189  int i, tot = lt->pntsu * lt->pntsv * lt->pntsw;
190 
191  for (i = 0, bp = lt->def; i < tot; i++, bp++) {
192  if (!use_selection || (bp->f1 & SELECT)) {
193  MDeformWeight *dw;
194 
195  dv = &lt->dvert[i];
196 
197  dw = BKE_defvert_find_index(dv, def_nr);
198  BKE_defvert_remove_group(dv, dw); /* dw can be NULL */
199  changed = true;
200  }
201  }
202  }
203  }
204 
205  return changed;
206 }
207 
208 bool BKE_object_defgroup_clear_all(Object *ob, const bool use_selection)
209 {
210  bDeformGroup *dg;
211  bool changed = false;
212 
213  const ListBase *defbase = BKE_object_defgroup_list(ob);
214 
215  for (dg = defbase->first; dg; dg = dg->next) {
216  if (BKE_object_defgroup_clear(ob, dg, use_selection)) {
217  changed = true;
218  }
219  }
220 
221  return changed;
222 }
223 
226 /* -------------------------------------------------------------------- */
230 static void object_defgroup_remove_update_users(Object *ob, const int idx)
231 {
232  int i, defbase_tot = BKE_object_defgroup_count(ob) + 1;
233  int *map = MEM_mallocN(sizeof(int) * defbase_tot, "vgroup del");
234 
235  map[idx] = map[0] = 0;
236  for (i = 1; i < idx; i++) {
237  map[i] = i;
238  }
239  for (i = idx + 1; i < defbase_tot; i++) {
240  map[i] = i - 1;
241  }
242 
244  MEM_freeN(map);
245 }
246 
247 static void object_defgroup_remove_common(Object *ob, bDeformGroup *dg, const int def_nr)
248 {
249  object_defgroup_remove_update_users(ob, def_nr + 1);
250 
251  /* Remove the group */
253 
254  BLI_freelinkN(defbase, dg);
255 
256  /* Update the active deform index if necessary */
257  const int active_index = BKE_object_defgroup_active_index_get(ob);
258  if (active_index > def_nr) {
259  BKE_object_defgroup_active_index_set(ob, active_index - 1);
260  }
261 
262  /* remove all dverts */
263  if (BLI_listbase_is_empty(defbase)) {
264  if (ob->type == OB_MESH) {
265  Mesh *me = ob->data;
267  me->dvert = NULL;
268  }
269  else if (ob->type == OB_LATTICE) {
270  Lattice *lt = object_defgroup_lattice_get((ID *)(ob->data));
271  MEM_SAFE_FREE(lt->dvert);
272  }
273  }
274  else if (BKE_object_defgroup_active_index_get(ob) < 1) {
275  /* Keep a valid active index if we still have some vgroups. */
277  }
278 }
279 
281 {
282  MDeformVert *dvert_array = NULL;
283  int dvert_tot = 0;
284  const ListBase *defbase = BKE_object_defgroup_list(ob);
285 
286  const int def_nr = BLI_findindex(defbase, dg);
287 
288  BLI_assert(def_nr != -1);
289 
290  BKE_object_defgroup_array_get(ob->data, &dvert_array, &dvert_tot);
291 
292  if (dvert_array) {
293  int i, j;
294  MDeformVert *dv;
295  for (i = 0, dv = dvert_array; i < dvert_tot; i++, dv++) {
296  MDeformWeight *dw;
297 
298  dw = BKE_defvert_find_index(dv, def_nr);
299  BKE_defvert_remove_group(dv, dw); /* dw can be NULL */
300 
301  /* inline, make into a function if anything else needs to do this */
302  for (j = 0; j < dv->totweight; j++) {
303  if (dv->dw[j].def_nr > def_nr) {
304  dv->dw[j].def_nr--;
305  }
306  }
307  /* done */
308  }
309  }
310 
311  object_defgroup_remove_common(ob, dg, def_nr);
312 }
313 
315 {
316  int i;
317  const ListBase *defbase = BKE_object_defgroup_list(ob);
318  const int def_nr = BLI_findindex(defbase, dg);
319 
320  BLI_assert(def_nr != -1);
321 
322  /* Make sure that no verts are using this group - if none were removed,
323  * we can skip next per-vert update. */
324  if (!BKE_object_defgroup_clear(ob, dg, false)) {
325  /* Nothing to do. */
326  }
327  /* Else, make sure that any groups with higher indices are adjusted accordingly */
328  else if (ob->type == OB_MESH) {
329  Mesh *me = ob->data;
330  BMEditMesh *em = me->edit_mesh;
331  const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT);
332 
333  BMIter iter;
334  BMVert *eve;
335  MDeformVert *dvert;
336 
337  BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
338  dvert = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset);
339 
340  if (dvert) {
341  for (i = 0; i < dvert->totweight; i++) {
342  if (dvert->dw[i].def_nr > def_nr) {
343  dvert->dw[i].def_nr--;
344  }
345  }
346  }
347  }
348  }
349  else if (ob->type == OB_LATTICE) {
350  Lattice *lt = ((Lattice *)(ob->data))->editlatt->latt;
351  BPoint *bp;
352  MDeformVert *dvert = lt->dvert;
353  int a, tot;
354 
355  if (dvert) {
356  tot = lt->pntsu * lt->pntsv * lt->pntsw;
357  for (a = 0, bp = lt->def; a < tot; a++, bp++, dvert++) {
358  for (i = 0; i < dvert->totweight; i++) {
359  if (dvert->dw[i].def_nr > def_nr) {
360  dvert->dw[i].def_nr--;
361  }
362  }
363  }
364  }
365  }
366 
367  object_defgroup_remove_common(ob, dg, def_nr);
368 }
369 
371 {
372  if (ob->type == OB_GPENCIL) {
373  BKE_gpencil_vgroup_remove(ob, defgroup);
374  }
375  else {
377  object_defgroup_remove_edit_mode(ob, defgroup);
378  }
379  else {
381  }
382 
384  }
385 }
386 
387 void BKE_object_defgroup_remove_all_ex(struct Object *ob, bool only_unlocked)
388 {
390 
391  bDeformGroup *dg = (bDeformGroup *)defbase->first;
392  const bool edit_mode = BKE_object_is_in_editmode_vgroup(ob);
393 
394  if (dg) {
395  while (dg) {
396  bDeformGroup *next_dg = dg->next;
397 
398  if (!only_unlocked || (dg->flag & DG_LOCK_WEIGHT) == 0) {
399  if (edit_mode) {
401  }
402  else {
404  }
405  }
406 
407  dg = next_dg;
408  }
409  }
410  else { /* defbase is empty... */
411  /* remove all dverts */
412  if (ob->type == OB_MESH) {
413  Mesh *me = ob->data;
415  me->dvert = NULL;
416  }
417  else if (ob->type == OB_LATTICE) {
418  Lattice *lt = object_defgroup_lattice_get((ID *)(ob->data));
419  MEM_SAFE_FREE(lt->dvert);
420  }
421  /* Fix counters/indices */
423  }
424 }
425 
427 {
429 }
430 
431 int *BKE_object_defgroup_index_map_create(Object *ob_src, Object *ob_dst, int *r_map_len)
432 {
433  const ListBase *src_defbase = BKE_object_defgroup_list(ob_src);
434  const ListBase *dst_defbase = BKE_object_defgroup_list(ob_dst);
435 
436  /* Build src to merged mapping of vgroup indices. */
437  if (BLI_listbase_is_empty(src_defbase) || BLI_listbase_is_empty(dst_defbase)) {
438  *r_map_len = 0;
439  return NULL;
440  }
441 
442  bDeformGroup *dg_src;
443  *r_map_len = BLI_listbase_count(src_defbase);
444  int *vgroup_index_map = MEM_malloc_arrayN(
445  *r_map_len, sizeof(*vgroup_index_map), "defgroup index map create");
446  bool is_vgroup_remap_needed = false;
447  int i;
448 
449  for (dg_src = src_defbase->first, i = 0; dg_src; dg_src = dg_src->next, i++) {
450  vgroup_index_map[i] = BKE_object_defgroup_name_index(ob_dst, dg_src->name);
451  is_vgroup_remap_needed = is_vgroup_remap_needed || (vgroup_index_map[i] != i);
452  }
453 
454  if (!is_vgroup_remap_needed) {
455  MEM_freeN(vgroup_index_map);
456  vgroup_index_map = NULL;
457  *r_map_len = 0;
458  }
459 
460  return vgroup_index_map;
461 }
462 
464  int dvert_len,
465  const int *map,
466  int map_len)
467 {
468  if (map == NULL || map_len == 0) {
469  return;
470  }
471 
472  MDeformVert *dv = dvert;
473  for (int i = 0; i < dvert_len; i++, dv++) {
474  int totweight = dv->totweight;
475  for (int j = 0; j < totweight; j++) {
476  int def_nr = dv->dw[j].def_nr;
477  if ((uint)def_nr < (uint)map_len && map[def_nr] != -1) {
478  dv->dw[j].def_nr = map[def_nr];
479  }
480  else {
481  totweight--;
482  dv->dw[j] = dv->dw[totweight];
483  j--;
484  }
485  }
486  if (totweight != dv->totweight) {
487  if (totweight) {
488  dv->dw = MEM_reallocN(dv->dw, sizeof(*dv->dw) * totweight);
489  }
490  else {
491  MEM_SAFE_FREE(dv->dw);
492  }
493  dv->totweight = totweight;
494  }
495  }
496 }
497 
498 bool BKE_object_defgroup_array_get(ID *id, MDeformVert **dvert_arr, int *dvert_tot)
499 {
500  if (id) {
501  switch (GS(id->name)) {
502  case ID_ME: {
503  Mesh *me = (Mesh *)id;
504  *dvert_arr = me->dvert;
505  *dvert_tot = me->totvert;
506  return true;
507  }
508  case ID_LT: {
510  *dvert_arr = lt->dvert;
511  *dvert_tot = lt->pntsu * lt->pntsv * lt->pntsw;
512  return true;
513  }
514  default:
515  break;
516  }
517  }
518 
519  *dvert_arr = NULL;
520  *dvert_tot = 0;
521  return false;
522 }
523 
526 /* --- functions for getting vgroup aligned maps --- */
527 
528 bool *BKE_object_defgroup_lock_flags_get(Object *ob, const int defbase_tot)
529 {
530  bool is_locked = false;
531  int i;
533  bool *lock_flags = MEM_mallocN(defbase_tot * sizeof(bool), "defflags");
534  bDeformGroup *defgroup;
535 
536  for (i = 0, defgroup = defbase->first; i < defbase_tot && defgroup;
537  defgroup = defgroup->next, i++) {
538  lock_flags[i] = ((defgroup->flag & DG_LOCK_WEIGHT) != 0);
539  is_locked |= lock_flags[i];
540  }
541  if (is_locked) {
542  return lock_flags;
543  }
544 
545  MEM_freeN(lock_flags);
546  return NULL;
547 }
548 
549 bool *BKE_object_defgroup_validmap_get(Object *ob, const int defbase_tot)
550 {
551  bDeformGroup *dg;
552  ModifierData *md;
553  bool *defgroup_validmap;
554  GHash *gh;
555  int i, step1 = 1;
556  const ListBase *defbase = BKE_object_defgroup_list(ob);
557  VirtualModifierData virtualModifierData;
558 
559  if (BLI_listbase_is_empty(defbase)) {
560  return NULL;
561  }
562 
563  gh = BLI_ghash_str_new_ex(__func__, defbase_tot);
564 
565  /* add all names to a hash table */
566  for (dg = defbase->first; dg; dg = dg->next) {
567  BLI_ghash_insert(gh, dg->name, NULL);
568  }
569 
570  BLI_assert(BLI_ghash_len(gh) == defbase_tot);
571 
572  /* now loop through the armature modifiers and identify deform bones */
573  for (md = ob->modifiers.first; md; md = !md->next && step1 ? (step1 = 0),
574  BKE_modifiers_get_virtual_modifierlist(ob, &virtualModifierData) :
575  md->next) {
577  continue;
578  }
579 
580  if (md->type == eModifierType_Armature) {
582 
583  if (amd->object && amd->object->pose) {
584  bPose *pose = amd->object->pose;
585  bPoseChannel *chan;
586 
587  for (chan = pose->chanbase.first; chan; chan = chan->next) {
588  void **val_p;
589  if (chan->bone->flag & BONE_NO_DEFORM) {
590  continue;
591  }
592 
593  val_p = BLI_ghash_lookup_p(gh, chan->name);
594  if (val_p) {
595  *val_p = POINTER_FROM_INT(1);
596  }
597  }
598  }
599  }
600  }
601 
602  defgroup_validmap = MEM_mallocN(sizeof(*defgroup_validmap) * defbase_tot, "wpaint valid map");
603 
604  /* add all names to a hash table */
605  for (dg = defbase->first, i = 0; dg; dg = dg->next, i++) {
606  defgroup_validmap[i] = (BLI_ghash_lookup(gh, dg->name) != NULL);
607  }
608 
609  BLI_assert(i == BLI_ghash_len(gh));
610 
611  BLI_ghash_free(gh, NULL, NULL);
612 
613  return defgroup_validmap;
614 }
615 
616 bool *BKE_object_defgroup_selected_get(Object *ob, int defbase_tot, int *r_dg_flags_sel_tot)
617 {
618  bool *dg_selection = MEM_mallocN(defbase_tot * sizeof(bool), __func__);
619  bDeformGroup *defgroup;
620  unsigned int i;
622  (*r_dg_flags_sel_tot) = 0;
623 
624  const ListBase *defbase = BKE_object_defgroup_list(ob);
625 
626  if (armob) {
627  bPose *pose = armob->pose;
628  for (i = 0, defgroup = defbase->first; i < defbase_tot && defgroup;
629  defgroup = defgroup->next, i++) {
630  bPoseChannel *pchan = BKE_pose_channel_find_name(pose, defgroup->name);
631  if (pchan && (pchan->bone->flag & BONE_SELECTED)) {
632  dg_selection[i] = true;
633  (*r_dg_flags_sel_tot) += 1;
634  }
635  else {
636  dg_selection[i] = false;
637  }
638  }
639  }
640  else {
641  memset(dg_selection, false, sizeof(*dg_selection) * defbase_tot);
642  }
643 
644  return dg_selection;
645 }
646 
647 bool BKE_object_defgroup_check_lock_relative(const bool *lock_flags,
648  const bool *validmap,
649  int index)
650 {
651  return validmap && validmap[index] && !(lock_flags && lock_flags[index]);
652 }
653 
655  const bool *lock_flags,
656  const bool *selected,
657  int sel_tot)
658 {
659  if (lock_flags == NULL) {
660  return true;
661  }
662 
663  if (selected == NULL || sel_tot <= 1) {
664  return true;
665  }
666 
667  for (int i = 0; i < defbase_tot; i++) {
668  if (selected[i] && lock_flags[i]) {
669  return false;
670  }
671  }
672 
673  return true;
674 }
675 
677  int defbase_tot, const bool *locked, const bool *deform, bool *r_locked, bool *r_unlocked)
678 {
679  if (!locked) {
680  if (r_unlocked != deform) {
681  memcpy(r_unlocked, deform, sizeof(bool) * defbase_tot);
682  }
683  if (r_locked) {
684  memset(r_locked, 0, sizeof(bool) * defbase_tot);
685  }
686  return;
687  }
688 
689  for (int i = 0; i < defbase_tot; i++) {
690  bool is_locked = locked[i];
691  bool is_deform = deform[i];
692 
693  r_locked[i] = is_deform && is_locked;
694  r_unlocked[i] = is_deform && !is_locked;
695  }
696 }
697 
699  int defbase_tot,
700  const bool *dg_selection,
701  bool *dg_flags_sel,
702  int *r_dg_flags_sel_tot)
703 {
704  const ListBase *defbase = BKE_object_defgroup_list(ob);
705 
706  bDeformGroup *defgroup;
707  unsigned int i;
708  int i_mirr;
709 
710  for (i = 0, defgroup = defbase->first; i < defbase_tot && defgroup;
711  defgroup = defgroup->next, i++) {
712  if (dg_selection[i]) {
713  char name_flip[MAXBONENAME];
714 
715  BLI_string_flip_side_name(name_flip, defgroup->name, false, sizeof(name_flip));
716  i_mirr = STREQ(name_flip, defgroup->name) ? i :
717  BKE_object_defgroup_name_index(ob, name_flip);
718 
719  if ((i_mirr >= 0 && i_mirr < defbase_tot) && (dg_flags_sel[i_mirr] == false)) {
720  dg_flags_sel[i_mirr] = true;
721  (*r_dg_flags_sel_tot) += 1;
722  }
723  }
724  }
725 }
726 
728  eVGroupSelect subset_type,
729  int *r_defgroup_tot,
730  int *r_subset_count)
731 {
732  bool *defgroup_validmap = NULL;
733 
734  *r_defgroup_tot = BKE_object_defgroup_count(ob);
735 
736  switch (subset_type) {
737  case WT_VGROUP_ACTIVE: {
738  const int def_nr_active = BKE_object_defgroup_active_index_get(ob) - 1;
739  defgroup_validmap = MEM_mallocN(*r_defgroup_tot * sizeof(*defgroup_validmap), __func__);
740  memset(defgroup_validmap, false, *r_defgroup_tot * sizeof(*defgroup_validmap));
741  if ((def_nr_active >= 0) && (def_nr_active < *r_defgroup_tot)) {
742  *r_subset_count = 1;
743  defgroup_validmap[def_nr_active] = true;
744  }
745  else {
746  *r_subset_count = 0;
747  }
748  break;
749  }
750  case WT_VGROUP_BONE_SELECT: {
751  defgroup_validmap = BKE_object_defgroup_selected_get(ob, *r_defgroup_tot, r_subset_count);
752  break;
753  }
754  case WT_VGROUP_BONE_DEFORM: {
755  int i;
756  defgroup_validmap = BKE_object_defgroup_validmap_get(ob, *r_defgroup_tot);
757  *r_subset_count = 0;
758  for (i = 0; i < *r_defgroup_tot; i++) {
759  if (defgroup_validmap[i] == true) {
760  *r_subset_count += 1;
761  }
762  }
763  break;
764  }
766  int i;
767  defgroup_validmap = BKE_object_defgroup_validmap_get(ob, *r_defgroup_tot);
768  *r_subset_count = 0;
769  for (i = 0; i < *r_defgroup_tot; i++) {
770  defgroup_validmap[i] = !defgroup_validmap[i];
771  if (defgroup_validmap[i] == true) {
772  *r_subset_count += 1;
773  }
774  }
775  break;
776  }
777  case WT_VGROUP_ALL:
778  default: {
779  defgroup_validmap = MEM_mallocN(*r_defgroup_tot * sizeof(*defgroup_validmap), __func__);
780  memset(defgroup_validmap, true, *r_defgroup_tot * sizeof(*defgroup_validmap));
781  *r_subset_count = *r_defgroup_tot;
782  break;
783  }
784  }
785 
786  return defgroup_validmap;
787 }
788 
789 void BKE_object_defgroup_subset_to_index_array(const bool *defgroup_validmap,
790  const int defgroup_tot,
791  int *r_defgroup_subset_map)
792 {
793  int i, j = 0;
794  for (i = 0; i < defgroup_tot; i++) {
795  if (defgroup_validmap[i]) {
796  r_defgroup_subset_map[j++] = i;
797  }
798  }
799 }
Blender kernel action and pose functionality.
struct bPoseChannel * BKE_pose_channel_find_name(const struct bPose *pose, const char *name)
bool CustomData_free_layer_active(struct CustomData *data, int type, int totelem)
Definition: customdata.cc:2895
@ CD_CALLOC
void * CustomData_add_layer(struct CustomData *data, int type, eCDAllocType alloctype, void *layer, int totelem)
Definition: customdata.cc:2776
int CustomData_get_offset(const struct CustomData *data, int type)
support for deformation groups and hooks.
int BKE_object_defgroup_active_index_get(const struct Object *ob)
struct ListBase * BKE_object_defgroup_list_mutable(struct Object *ob)
Definition: deform.c:552
struct MDeformWeight * BKE_defvert_find_index(const struct MDeformVert *dv, int defgroup)
void BKE_object_defgroup_active_index_set(struct Object *ob, int new_index)
Definition: deform.c:568
int BKE_object_defgroup_name_index(const struct Object *ob, const char *name)
const struct ListBase * BKE_object_defgroup_list(const struct Object *ob)
struct bDeformGroup * BKE_object_defgroup_new(struct Object *ob, const char *name)
Definition: deform.c:43
void BKE_defvert_remove_group(struct MDeformVert *dvert, struct MDeformWeight *dw)
Definition: deform.c:804
int BKE_object_defgroup_count(const struct Object *ob)
void BKE_gpencil_vgroup_remove(struct Object *ob, struct bDeformGroup *defgroup)
Definition: gpencil.c:1840
struct ModifierData * BKE_modifiers_get_virtual_modifierlist(const struct Object *ob, struct VirtualModifierData *data)
General operations, lookup, etc. for blender objects.
void BKE_object_batch_cache_dirty_tag(struct Object *ob)
struct Object * BKE_object_pose_armature_get(struct Object *ob)
Definition: object.cc:2511
bool BKE_object_is_in_editmode_vgroup(const struct Object *ob)
Functions for dealing with objects and deform verts, used by painting and tools.
#define BLI_assert(a)
Definition: BLI_assert.h:46
GHash * BLI_ghash_str_new_ex(const char *info, unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
void * BLI_ghash_lookup(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:734
unsigned int BLI_ghash_len(const GHash *gh) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:705
void BLI_ghash_insert(GHash *gh, void *key, void *val)
Definition: BLI_ghash.c:710
void ** BLI_ghash_lookup_p(GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:748
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:863
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:269
void BLI_freelinkN(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:239
int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
size_t BLI_string_flip_side_name(char *r_name, const char *from_name, bool strip_number, size_t name_len)
Definition: string_utils.c:112
unsigned int uint
Definition: BLI_sys_types.h:67
#define POINTER_FROM_INT(i)
#define STREQ(a, b)
#define DATA_(msgid)
@ ID_ME
Definition: DNA_ID_enums.h:48
@ ID_LT
Definition: DNA_ID_enums.h:54
#define MAXBONENAME
@ BONE_SELECTED
@ BONE_NO_DEFORM
@ CD_MDEFORMVERT
@ eModifierMode_Virtual
@ eModifierMode_Realtime
@ eModifierType_Explode
@ eModifierType_Cloth
@ eModifierType_Armature
Object is a sort of wrapper for general info.
@ OB_LATTICE
@ OB_MESH
@ OB_GPENCIL
#define OB_TYPE_SUPPORT_VGROUP(_type)
#define DG_LOCK_WEIGHT
#define PSYS_TOT_VG
eVGroupSelect
@ WT_VGROUP_BONE_SELECT
@ WT_VGROUP_ALL
@ WT_VGROUP_BONE_DEFORM_OFF
@ WT_VGROUP_ACTIVE
@ WT_VGROUP_BONE_DEFORM
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
#define MEM_reallocN(vmemh, len)
@ BM_ELEM_SELECT
Definition: bmesh_class.h:471
#define BM_ELEM_CD_GET_VOID_P(ele, offset)
Definition: bmesh_class.h:541
#define BM_elem_flag_test(ele, hflag)
Definition: bmesh_inline.h:12
#define BM_ITER_MESH(ele, iter, bm, itype)
@ BM_VERTS_OF_MESH
#define SELECT
#define GS(x)
Definition: iris.c:225
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
Definition: mallocn.c:34
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
static unsigned a[3]
Definition: RandGen.cpp:78
SocketIndexByIdentifierMap * map
bool BKE_object_defgroup_check_lock_relative(const bool *lock_flags, const bool *validmap, int index)
bool BKE_object_defgroup_array_get(ID *id, MDeformVert **dvert_arr, int *dvert_tot)
MDeformVert * BKE_object_defgroup_data_create(ID *id)
void BKE_object_defgroup_split_locked_validmap(int defbase_tot, const bool *locked, const bool *deform, bool *r_locked, bool *r_unlocked)
static void object_defgroup_remove_update_users(Object *ob, const int idx)
void 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)
bool BKE_object_defgroup_clear_all(Object *ob, const bool use_selection)
void BKE_object_defgroup_subset_to_index_array(const bool *defgroup_validmap, const int defgroup_tot, int *r_defgroup_subset_map)
bool BKE_object_defgroup_clear(Object *ob, bDeformGroup *dg, const bool use_selection)
bool * BKE_object_defgroup_validmap_get(Object *ob, const int defbase_tot)
int * BKE_object_defgroup_index_map_create(Object *ob_src, Object *ob_dst, int *r_map_len)
bool * BKE_object_defgroup_selected_get(Object *ob, int defbase_tot, int *r_dg_flags_sel_tot)
void BKE_object_defgroup_remove_all_ex(struct Object *ob, bool only_unlocked)
static void object_defgroup_remove_common(Object *ob, bDeformGroup *dg, const int def_nr)
bool * BKE_object_defgroup_subset_from_select_type(Object *ob, eVGroupSelect subset_type, int *r_defgroup_tot, int *r_subset_count)
static void object_defgroup_remove_edit_mode(Object *ob, bDeformGroup *dg)
bDeformGroup * BKE_object_defgroup_add(Object *ob)
bool BKE_object_defgroup_check_lock_relative_multi(int defbase_tot, const bool *lock_flags, const bool *selected, int sel_tot)
bDeformGroup * BKE_object_defgroup_add_name(Object *ob, const char *name)
Definition: object_deform.c:95
bool * BKE_object_defgroup_lock_flags_get(Object *ob, const int defbase_tot)
void BKE_object_defgroup_index_map_apply(MDeformVert *dvert, int dvert_len, const int *map, int map_len)
static void object_defgroup_remove_object_mode(Object *ob, bDeformGroup *dg)
void BKE_object_defgroup_remap_update_users(Object *ob, const int *map)
Definition: object_deform.c:52
static Lattice * object_defgroup_lattice_get(ID *id)
Definition: object_deform.c:45
void BKE_object_defgroup_remove_all(struct Object *ob)
void BKE_object_defgroup_remove(Object *ob, bDeformGroup *defgroup)
struct BMesh * bm
Definition: BKE_editmesh.h:40
CustomData vdata
Definition: bmesh_class.h:337
uint8_t f1
struct ClothSimSettings * sim_parms
struct Lattice * latt
Definition: DNA_ID.h:368
char name[66]
Definition: DNA_ID.h:378
struct MDeformVert * dvert
struct EditLatt * editlatt
struct BPoint * def
void * first
Definition: DNA_listBase.h:31
struct MDeformWeight * dw
unsigned int def_nr
struct BMEditMesh * edit_mesh
CustomData vdata
struct MVert * mvert
struct MDeformVert * dvert
int totvert
struct ModifierData * next
ListBase particlesystem
struct bPose * pose
ListBase modifiers
struct SoftBody * soft
void * data
struct ParticleSystem * next
struct bDeformGroup * next
struct Bone * bone
struct bPoseChannel * next
ListBase chanbase