Blender  V2.93
object_deform.c
Go to the documentation of this file.
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 
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 /* -------------------------------------------------------------------- */
59 {
60  Lattice *lt = (Lattice *)id;
61  BLI_assert(GS(id->name) == ID_LT);
62  return (lt->editlatt) ? lt->editlatt->latt : lt;
63 }
64 
73 {
74  ModifierData *md;
75  ParticleSystem *psys;
76  int a;
77 
78  /* these cases don't use names to refer to vertex groups, so when
79  * they get removed the numbers get out of sync, this corrects that */
80 
81  if (ob->soft) {
82  ob->soft->vertgroup = map[ob->soft->vertgroup];
83  }
84 
85  for (md = ob->modifiers.first; md; md = md->next) {
86  if (md->type == eModifierType_Explode) {
88  emd->vgroup = map[emd->vgroup];
89  }
90  else if (md->type == eModifierType_Cloth) {
92  ClothSimSettings *clsim = clmd->sim_parms;
93 
94  if (clsim) {
95  clsim->vgroup_mass = map[clsim->vgroup_mass];
96  clsim->vgroup_bend = map[clsim->vgroup_bend];
97  clsim->vgroup_struct = map[clsim->vgroup_struct];
98  }
99  }
100  }
101 
102  for (psys = ob->particlesystem.first; psys; psys = psys->next) {
103  for (a = 0; a < PSYS_TOT_VG; a++) {
104  psys->vgroup[a] = map[psys->vgroup[a]];
105  }
106  }
107 }
110 /* -------------------------------------------------------------------- */
118 {
119  bDeformGroup *defgroup;
120 
121  if (!ob || !OB_TYPE_SUPPORT_VGROUP(ob->type)) {
122  return NULL;
123  }
124 
125  defgroup = BKE_object_defgroup_new(ob, name);
126 
127  ob->actdef = BLI_listbase_count(&ob->defbase);
128 
129  return defgroup;
130 }
131 
136 {
137  return BKE_object_defgroup_add_name(ob, DATA_("Group"));
138 }
139 
144 {
145  if (GS(id->name) == ID_ME) {
146  Mesh *me = (Mesh *)id;
148  return me->dvert;
149  }
150  if (GS(id->name) == ID_LT) {
151  Lattice *lt = (Lattice *)id;
152  lt->dvert = MEM_callocN(sizeof(MDeformVert) * lt->pntsu * lt->pntsv * lt->pntsw,
153  "lattice deformVert");
154  return lt->dvert;
155  }
156 
157  return NULL;
158 }
161 /* -------------------------------------------------------------------- */
171 bool BKE_object_defgroup_clear(Object *ob, bDeformGroup *dg, const bool use_selection)
172 {
173  MDeformVert *dv;
174  const int def_nr = BLI_findindex(&ob->defbase, dg);
175  bool changed = false;
176 
177  if (ob->type == OB_MESH) {
178  Mesh *me = ob->data;
179 
180  if (me->edit_mesh) {
181  BMEditMesh *em = me->edit_mesh;
182  const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT);
183 
184  if (cd_dvert_offset != -1) {
185  BMVert *eve;
186  BMIter iter;
187 
188  BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
189  dv = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset);
190 
191  if (dv && dv->dw && (!use_selection || BM_elem_flag_test(eve, BM_ELEM_SELECT))) {
192  MDeformWeight *dw = BKE_defvert_find_index(dv, def_nr);
193  BKE_defvert_remove_group(dv, dw); /* dw can be NULL */
194  changed = true;
195  }
196  }
197  }
198  }
199  else {
200  if (me->dvert) {
201  MVert *mv;
202  int i;
203 
204  mv = me->mvert;
205  dv = me->dvert;
206 
207  for (i = 0; i < me->totvert; i++, mv++, dv++) {
208  if (dv->dw && (!use_selection || (mv->flag & SELECT))) {
209  MDeformWeight *dw = BKE_defvert_find_index(dv, def_nr);
210  BKE_defvert_remove_group(dv, dw); /* dw can be NULL */
211  changed = true;
212  }
213  }
214  }
215  }
216  }
217  else if (ob->type == OB_LATTICE) {
218  Lattice *lt = object_defgroup_lattice_get((ID *)(ob->data));
219 
220  if (lt->dvert) {
221  BPoint *bp;
222  int i, tot = lt->pntsu * lt->pntsv * lt->pntsw;
223 
224  for (i = 0, bp = lt->def; i < tot; i++, bp++) {
225  if (!use_selection || (bp->f1 & SELECT)) {
226  MDeformWeight *dw;
227 
228  dv = &lt->dvert[i];
229 
230  dw = BKE_defvert_find_index(dv, def_nr);
231  BKE_defvert_remove_group(dv, dw); /* dw can be NULL */
232  changed = true;
233  }
234  }
235  }
236  }
237 
238  return changed;
239 }
240 
247 bool BKE_object_defgroup_clear_all(Object *ob, const bool use_selection)
248 {
249  bDeformGroup *dg;
250  bool changed = false;
251 
252  for (dg = ob->defbase.first; dg; dg = dg->next) {
253  if (BKE_object_defgroup_clear(ob, dg, use_selection)) {
254  changed = true;
255  }
256  }
257 
258  return changed;
259 }
262 /* -------------------------------------------------------------------- */
266 static void object_defgroup_remove_update_users(Object *ob, const int idx)
267 {
268  int i, defbase_tot = BLI_listbase_count(&ob->defbase) + 1;
269  int *map = MEM_mallocN(sizeof(int) * defbase_tot, "vgroup del");
270 
271  map[idx] = map[0] = 0;
272  for (i = 1; i < idx; i++) {
273  map[i] = i;
274  }
275  for (i = idx + 1; i < defbase_tot; i++) {
276  map[i] = i - 1;
277  }
278 
280  MEM_freeN(map);
281 }
282 
283 static void object_defgroup_remove_common(Object *ob, bDeformGroup *dg, const int def_nr)
284 {
285  object_defgroup_remove_update_users(ob, def_nr + 1);
286 
287  /* Remove the group */
288  BLI_freelinkN(&ob->defbase, dg);
289 
290  /* Update the active deform index if necessary */
291  if (ob->actdef > def_nr) {
292  ob->actdef--;
293  }
294 
295  /* remove all dverts */
296  if (BLI_listbase_is_empty(&ob->defbase)) {
297  if (ob->type == OB_MESH) {
298  Mesh *me = ob->data;
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 
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 = BKE_defvert_find_index(dv, def_nr);
332  BKE_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 
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,
355  * we can skip next per-vert update. */
356  if (!BKE_object_defgroup_clear(ob, dg, false)) {
357  /* Nothing to do. */
358  }
359  /* Else, make sure that any groups with higher indices are adjusted accordingly */
360  else if (ob->type == OB_MESH) {
361  Mesh *me = ob->data;
362  BMEditMesh *em = me->edit_mesh;
363  const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT);
364 
365  BMIter iter;
366  BMVert *eve;
367  MDeformVert *dvert;
368 
369  BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
370  dvert = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset);
371 
372  if (dvert) {
373  for (i = 0; i < dvert->totweight; i++) {
374  if (dvert->dw[i].def_nr > def_nr) {
375  dvert->dw[i].def_nr--;
376  }
377  }
378  }
379  }
380  }
381  else if (ob->type == OB_LATTICE) {
382  Lattice *lt = ((Lattice *)(ob->data))->editlatt->latt;
383  BPoint *bp;
384  MDeformVert *dvert = lt->dvert;
385  int a, tot;
386 
387  if (dvert) {
388  tot = lt->pntsu * lt->pntsv * lt->pntsw;
389  for (a = 0, bp = lt->def; a < tot; a++, bp++, dvert++) {
390  for (i = 0; i < dvert->totweight; i++) {
391  if (dvert->dw[i].def_nr > def_nr) {
392  dvert->dw[i].def_nr--;
393  }
394  }
395  }
396  }
397  }
398 
399  object_defgroup_remove_common(ob, dg, def_nr);
400 }
401 
406 {
407  if (ob->type == OB_GPENCIL) {
408  BKE_gpencil_vgroup_remove(ob, defgroup);
409  }
410  else {
412  object_defgroup_remove_edit_mode(ob, defgroup);
413  }
414  else {
416  }
417 
419  }
420 }
421 
426 void BKE_object_defgroup_remove_all_ex(struct Object *ob, bool only_unlocked)
427 {
428  bDeformGroup *dg = (bDeformGroup *)ob->defbase.first;
429  const bool edit_mode = BKE_object_is_in_editmode_vgroup(ob);
430 
431  if (dg) {
432  while (dg) {
433  bDeformGroup *next_dg = dg->next;
434 
435  if (!only_unlocked || (dg->flag & DG_LOCK_WEIGHT) == 0) {
436  if (edit_mode) {
438  }
439  else {
441  }
442  }
443 
444  dg = next_dg;
445  }
446  }
447  else { /* ob->defbase is empty... */
448  /* remove all dverts */
449  if (ob->type == OB_MESH) {
450  Mesh *me = ob->data;
452  me->dvert = NULL;
453  }
454  else if (ob->type == OB_LATTICE) {
455  Lattice *lt = object_defgroup_lattice_get((ID *)(ob->data));
456  if (lt->dvert) {
457  MEM_freeN(lt->dvert);
458  lt->dvert = NULL;
459  }
460  }
461  /* Fix counters/indices */
462  ob->actdef = 0;
463  }
464 }
465 
470 {
472 }
473 
479 int *BKE_object_defgroup_index_map_create(Object *ob_src, Object *ob_dst, int *r_map_len)
480 {
481  /* Build src to merged mapping of vgroup indices. */
482  if (BLI_listbase_is_empty(&ob_src->defbase) || BLI_listbase_is_empty(&ob_dst->defbase)) {
483  *r_map_len = 0;
484  return NULL;
485  }
486 
487  bDeformGroup *dg_src;
488  *r_map_len = BLI_listbase_count(&ob_src->defbase);
489  int *vgroup_index_map = MEM_malloc_arrayN(
490  *r_map_len, sizeof(*vgroup_index_map), "defgroup index map create");
491  bool is_vgroup_remap_needed = false;
492  int i;
493 
494  for (dg_src = ob_src->defbase.first, i = 0; dg_src; dg_src = dg_src->next, i++) {
495  vgroup_index_map[i] = BKE_object_defgroup_name_index(ob_dst, dg_src->name);
496  is_vgroup_remap_needed = is_vgroup_remap_needed || (vgroup_index_map[i] != i);
497  }
498 
499  if (!is_vgroup_remap_needed) {
500  MEM_freeN(vgroup_index_map);
501  vgroup_index_map = NULL;
502  *r_map_len = 0;
503  }
504 
505  return vgroup_index_map;
506 }
507 
509  int dvert_len,
510  const int *map,
511  int map_len)
512 {
513  if (map == NULL || map_len == 0) {
514  return;
515  }
516 
517  MDeformVert *dv = dvert;
518  for (int i = 0; i < dvert_len; i++, dv++) {
519  int totweight = dv->totweight;
520  for (int j = 0; j < totweight; j++) {
521  int def_nr = dv->dw[j].def_nr;
522  if ((uint)def_nr < (uint)map_len && map[def_nr] != -1) {
523  dv->dw[j].def_nr = map[def_nr];
524  }
525  else {
526  totweight--;
527  dv->dw[j] = dv->dw[totweight];
528  j--;
529  }
530  }
531  if (totweight != dv->totweight) {
532  if (totweight) {
533  dv->dw = MEM_reallocN(dv->dw, sizeof(*dv->dw) * totweight);
534  }
535  else {
536  MEM_SAFE_FREE(dv->dw);
537  }
538  dv->totweight = totweight;
539  }
540  }
541 }
542 
548 bool BKE_object_defgroup_array_get(ID *id, MDeformVert **dvert_arr, int *dvert_tot)
549 {
550  if (id) {
551  switch (GS(id->name)) {
552  case ID_ME: {
553  Mesh *me = (Mesh *)id;
554  *dvert_arr = me->dvert;
555  *dvert_tot = me->totvert;
556  return true;
557  }
558  case ID_LT: {
560  *dvert_arr = lt->dvert;
561  *dvert_tot = lt->pntsu * lt->pntsv * lt->pntsw;
562  return true;
563  }
564  default:
565  break;
566  }
567  }
568 
569  *dvert_arr = NULL;
570  *dvert_tot = 0;
571  return false;
572 }
575 /* --- functions for getting vgroup aligned maps --- */
576 
581 bool *BKE_object_defgroup_lock_flags_get(Object *ob, const int defbase_tot)
582 {
583  bool is_locked = false;
584  int i;
585  // int defbase_tot = BLI_listbase_count(&ob->defbase);
586  bool *lock_flags = MEM_mallocN(defbase_tot * sizeof(bool), "defflags");
587  bDeformGroup *defgroup;
588 
589  for (i = 0, defgroup = ob->defbase.first; i < defbase_tot && defgroup;
590  defgroup = defgroup->next, i++) {
591  lock_flags[i] = ((defgroup->flag & DG_LOCK_WEIGHT) != 0);
592  is_locked |= lock_flags[i];
593  }
594  if (is_locked) {
595  return lock_flags;
596  }
597 
598  MEM_freeN(lock_flags);
599  return NULL;
600 }
601 
602 bool *BKE_object_defgroup_validmap_get(Object *ob, const int defbase_tot)
603 {
604  bDeformGroup *dg;
605  ModifierData *md;
606  bool *defgroup_validmap;
607  GHash *gh;
608  int i, step1 = 1;
609  // int defbase_tot = BLI_listbase_count(&ob->defbase);
610  VirtualModifierData virtualModifierData;
611 
612  if (BLI_listbase_is_empty(&ob->defbase)) {
613  return NULL;
614  }
615 
616  gh = BLI_ghash_str_new_ex(__func__, defbase_tot);
617 
618  /* add all names to a hash table */
619  for (dg = ob->defbase.first; dg; dg = dg->next) {
620  BLI_ghash_insert(gh, dg->name, NULL);
621  }
622 
623  BLI_assert(BLI_ghash_len(gh) == defbase_tot);
624 
625  /* now loop through the armature modifiers and identify deform bones */
626  for (md = ob->modifiers.first; md; md = !md->next && step1 ? (step1 = 0),
627  BKE_modifiers_get_virtual_modifierlist(ob, &virtualModifierData) :
628  md->next) {
630  continue;
631  }
632 
633  if (md->type == eModifierType_Armature) {
635 
636  if (amd->object && amd->object->pose) {
637  bPose *pose = amd->object->pose;
638  bPoseChannel *chan;
639 
640  for (chan = pose->chanbase.first; chan; chan = chan->next) {
641  void **val_p;
642  if (chan->bone->flag & BONE_NO_DEFORM) {
643  continue;
644  }
645 
646  val_p = BLI_ghash_lookup_p(gh, chan->name);
647  if (val_p) {
648  *val_p = POINTER_FROM_INT(1);
649  }
650  }
651  }
652  }
653  }
654 
655  defgroup_validmap = MEM_mallocN(sizeof(*defgroup_validmap) * defbase_tot, "wpaint valid map");
656 
657  /* add all names to a hash table */
658  for (dg = ob->defbase.first, i = 0; dg; dg = dg->next, i++) {
659  defgroup_validmap[i] = (BLI_ghash_lookup(gh, dg->name) != NULL);
660  }
661 
662  BLI_assert(i == BLI_ghash_len(gh));
663 
664  BLI_ghash_free(gh, NULL, NULL);
665 
666  return defgroup_validmap;
667 }
668 
669 /* Returns total selected vgroups,
670  * wpi.defbase_sel is assumed malloc'd, all values are set */
671 bool *BKE_object_defgroup_selected_get(Object *ob, int defbase_tot, int *r_dg_flags_sel_tot)
672 {
673  bool *dg_selection = MEM_mallocN(defbase_tot * sizeof(bool), __func__);
674  bDeformGroup *defgroup;
675  unsigned int i;
677  (*r_dg_flags_sel_tot) = 0;
678 
679  if (armob) {
680  bPose *pose = armob->pose;
681  for (i = 0, defgroup = ob->defbase.first; i < defbase_tot && defgroup;
682  defgroup = defgroup->next, i++) {
683  bPoseChannel *pchan = BKE_pose_channel_find_name(pose, defgroup->name);
684  if (pchan && (pchan->bone->flag & BONE_SELECTED)) {
685  dg_selection[i] = true;
686  (*r_dg_flags_sel_tot) += 1;
687  }
688  else {
689  dg_selection[i] = false;
690  }
691  }
692  }
693  else {
694  memset(dg_selection, false, sizeof(*dg_selection) * defbase_tot);
695  }
696 
697  return dg_selection;
698 }
699 
705 bool BKE_object_defgroup_check_lock_relative(const bool *lock_flags,
706  const bool *validmap,
707  int index)
708 {
709  return validmap && validmap[index] && !(lock_flags && lock_flags[index]);
710 }
711 
718  const bool *lock_flags,
719  const bool *selected,
720  int sel_tot)
721 {
722  if (lock_flags == NULL) {
723  return true;
724  }
725 
726  if (selected == NULL || sel_tot <= 1) {
727  return true;
728  }
729 
730  for (int i = 0; i < defbase_tot; i++) {
731  if (selected[i] && lock_flags[i]) {
732  return false;
733  }
734  }
735 
736  return true;
737 }
738 
745  int defbase_tot, const bool *locked, const bool *deform, bool *r_locked, bool *r_unlocked)
746 {
747  if (!locked) {
748  if (r_unlocked != deform) {
749  memcpy(r_unlocked, deform, sizeof(bool) * defbase_tot);
750  }
751  if (r_locked) {
752  memset(r_locked, 0, sizeof(bool) * defbase_tot);
753  }
754  return;
755  }
756 
757  for (int i = 0; i < defbase_tot; i++) {
758  bool is_locked = locked[i];
759  bool is_deform = deform[i];
760 
761  r_locked[i] = is_deform && is_locked;
762  r_unlocked[i] = is_deform && !is_locked;
763  }
764 }
765 
772  int defbase_tot,
773  const bool *dg_selection,
774  bool *dg_flags_sel,
775  int *r_dg_flags_sel_tot)
776 {
777  bDeformGroup *defgroup;
778  unsigned int i;
779  int i_mirr;
780 
781  for (i = 0, defgroup = ob->defbase.first; i < defbase_tot && defgroup;
782  defgroup = defgroup->next, i++) {
783  if (dg_selection[i]) {
784  char name_flip[MAXBONENAME];
785 
786  BLI_string_flip_side_name(name_flip, defgroup->name, false, sizeof(name_flip));
787  i_mirr = STREQ(name_flip, defgroup->name) ? i :
788  BKE_object_defgroup_name_index(ob, name_flip);
789 
790  if ((i_mirr >= 0 && i_mirr < defbase_tot) && (dg_flags_sel[i_mirr] == false)) {
791  dg_flags_sel[i_mirr] = true;
792  (*r_dg_flags_sel_tot) += 1;
793  }
794  }
795  }
796 }
797 
802  eVGroupSelect subset_type,
803  int *r_defgroup_tot,
804  int *r_subset_count)
805 {
806  bool *defgroup_validmap = NULL;
807  *r_defgroup_tot = BLI_listbase_count(&ob->defbase);
808 
809  switch (subset_type) {
810  case WT_VGROUP_ACTIVE: {
811  const int def_nr_active = ob->actdef - 1;
812  defgroup_validmap = MEM_mallocN(*r_defgroup_tot * sizeof(*defgroup_validmap), __func__);
813  memset(defgroup_validmap, false, *r_defgroup_tot * sizeof(*defgroup_validmap));
814  if ((def_nr_active >= 0) && (def_nr_active < *r_defgroup_tot)) {
815  *r_subset_count = 1;
816  defgroup_validmap[def_nr_active] = true;
817  }
818  else {
819  *r_subset_count = 0;
820  }
821  break;
822  }
823  case WT_VGROUP_BONE_SELECT: {
824  defgroup_validmap = BKE_object_defgroup_selected_get(ob, *r_defgroup_tot, r_subset_count);
825  break;
826  }
827  case WT_VGROUP_BONE_DEFORM: {
828  int i;
829  defgroup_validmap = BKE_object_defgroup_validmap_get(ob, *r_defgroup_tot);
830  *r_subset_count = 0;
831  for (i = 0; i < *r_defgroup_tot; i++) {
832  if (defgroup_validmap[i] == true) {
833  *r_subset_count += 1;
834  }
835  }
836  break;
837  }
839  int i;
840  defgroup_validmap = BKE_object_defgroup_validmap_get(ob, *r_defgroup_tot);
841  *r_subset_count = 0;
842  for (i = 0; i < *r_defgroup_tot; i++) {
843  defgroup_validmap[i] = !defgroup_validmap[i];
844  if (defgroup_validmap[i] == true) {
845  *r_subset_count += 1;
846  }
847  }
848  break;
849  }
850  case WT_VGROUP_ALL:
851  default: {
852  defgroup_validmap = MEM_mallocN(*r_defgroup_tot * sizeof(*defgroup_validmap), __func__);
853  memset(defgroup_validmap, true, *r_defgroup_tot * sizeof(*defgroup_validmap));
854  *r_subset_count = *r_defgroup_tot;
855  break;
856  }
857  }
858 
859  return defgroup_validmap;
860 }
861 
865 void BKE_object_defgroup_subset_to_index_array(const bool *defgroup_validmap,
866  const int defgroup_tot,
867  int *r_defgroup_subset_map)
868 {
869  int i, j = 0;
870  for (i = 0; i < defgroup_tot; i++) {
871  if (defgroup_validmap[i]) {
872  r_defgroup_subset_map[j++] = i;
873  }
874  }
875 }
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.c:2707
@ CD_CALLOC
void * CustomData_add_layer(struct CustomData *data, int type, eCDAllocType alloctype, void *layer, int totelem)
Definition: customdata.c:2620
int CustomData_get_offset(const struct CustomData *data, int type)
support for deformation groups and hooks.
int BKE_object_defgroup_name_index(const struct Object *ob, const char *name)
struct bDeformGroup * BKE_object_defgroup_new(struct Object *ob, const char *name)
Definition: deform.c:57
struct MDeformWeight * BKE_defvert_find_index(const struct MDeformVert *dv, const int defgroup)
void BKE_defvert_remove_group(struct MDeformVert *dvert, struct MDeformWeight *dw)
Definition: deform.c:754
void BKE_gpencil_vgroup_remove(struct Object *ob, struct bDeformGroup *defgroup)
Definition: gpencil.c:2025
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.c:2487
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:58
unsigned int BLI_ghash_len(GHash *gh) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:744
GHash * BLI_ghash_str_new_ex(const char *info, const unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
void BLI_ghash_insert(GHash *gh, void *key, void *val)
Definition: BLI_ghash.c:756
void ** BLI_ghash_lookup_p(GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:830
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:1008
void * BLI_ghash_lookup(GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:803
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:124
void BLI_freelinkN(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:281
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)
void BLI_string_flip_side_name(char *r_name, const char *from_name, const bool strip_number, const size_t name_len)
Definition: string_utils.c:159
unsigned int uint
Definition: BLI_sys_types.h:83
#define POINTER_FROM_INT(i)
#define STREQ(a, b)
#define DATA_(msgid)
@ ID_ME
Definition: DNA_ID_enums.h:60
@ ID_LT
Definition: DNA_ID_enums.h:66
#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.
#define OB_TYPE_SUPPORT_VGROUP(_type)
#define DG_LOCK_WEIGHT
@ OB_LATTICE
@ OB_MESH
@ OB_GPENCIL
#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:530
#define BM_elem_flag_test(ele, hflag)
Definition: bmesh_inline.h:26
#define BM_ITER_MESH(ele, iter, bm, itype)
@ BM_VERTS_OF_MESH
#define SELECT
#define GS(x)
Definition: iris.c:241
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
Definition: mallocn.c:48
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:47
static unsigned a[3]
Definition: RandGen.cpp:92
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)
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:72
static Lattice * object_defgroup_lattice_get(ID *id)
Definition: object_deform.c:58
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:52
CustomData vdata
Definition: bmesh_class.h:337
uint8_t f1
struct ClothSimSettings * sim_parms
struct Lattice * latt
Definition: DNA_ID.h:273
char name[66]
Definition: DNA_ID.h:283
struct MDeformVert * dvert
struct EditLatt * editlatt
struct BPoint * def
void * first
Definition: DNA_listBase.h:47
struct MDeformWeight * dw
unsigned int def_nr
struct BMEditMesh * edit_mesh
struct MVert * mvert
struct MDeformVert * dvert
int totvert
struct ModifierData * next
ListBase particlesystem
ListBase defbase
struct bPose * pose
ListBase modifiers
struct SoftBody * soft
unsigned short actdef
void * data
struct ParticleSystem * next
struct bDeformGroup * next
struct Bone * bone
struct bPoseChannel * next
ListBase chanbase